views:

9827

answers:

4

I have a page, lets call it SourceTypes.aspx, that has a a GridView that is displaying a list of Source Types. Part of the GridView is a DataKey, SourceTypeID. If source TypeID is passed to the page via a query sting, how to I put the Gridview into Edit mode for the appropriate row based on the SourceTypeID?

The GridView is bound to a SQlDataSource object.

I have a feeling I am going to kick myself when the answer appears!!

I have looked at Putting a gridview row in edit mode programmatically but it is some what lacking in specifics

+2  A: 

It's a little trickier when you want to put it into edit mode based on data. You tell the datagrid which of it's displayed rows is editable, not which data you want to be editable, so you'll need to go through each of the rows in the grid, see if it matches the id, and set the EditItemIndex to the appropriate value and rebind.

You could look at the source data and get the row number from that before you bind, but then you may have problems with paging, sorting etc.

It's a bit messy having to rebind the grid, but I can't think of a better way off the top of my head.

public partial class _Default : System.Web.UI.Page
{

    private DataTable GetData()
    {
        DataTable tTable = new DataTable();
        tTable.Columns.Add(new DataColumn("Column1", typeof(int)));
        tTable.Columns.Add(new DataColumn("Column2", typeof(string)));

        DataRow tRow = tTable.NewRow();
        tRow["Column1"] = 1;
        tRow["Column2"] = "Test1";
        tTable.Rows.Add(tRow);

        tRow = tTable.NewRow();
        tRow["Column1"] = 2;
        tRow["Column2"] = "Test2";
        tTable.Rows.Add(tRow);

        tRow = tTable.NewRow();
        tRow["Column1"] = 3;
        tRow["Column2"] = "Test3";
        tTable.Rows.Add(tRow);

        tRow = tTable.NewRow();
        tRow["Column1"] = 4;
        tRow["Column2"] = "Test4";
        tTable.Rows.Add(tRow);

        tRow = tTable.NewRow();
        tRow["Column1"] = 5;
        tRow["Column2"] = "Test5";
        tTable.Rows.Add(tRow);

        return tTable;
    }

    private void BindData()
    {
        DataTable tTable = GetData();

        TestGrid.DataSource = tTable;
        TestGrid.DataBind();

        if (!String.IsNullOrEmpty(Request.QueryString["edit"]))
        {
            foreach (DataGridItem tRow in TestGrid.Items)
            {
                if (tRow.Cells[0].Text == Request.QueryString["edit"])
                    TestGrid.EditItemIndex = tRow.ItemIndex;
            }
            TestGrid.DataBind();
        }
    }

    protected void Page_Load(object sender, EventArgs e)
    {
        if (!Page.IsPostBack)
            BindData();
    }
}

You should be able to fire that up (with a datagrid added to the ASPX obviously) then put ?edit= on the end of the URL to get it to open the relevent entry in edit mode.

Steven Robbins
Thanks Steve, at what point in the page life cycle whould be best for this? Any chance of a brief sample?
Jon P
Page Load (in the !IsPostBack) - I'll see if I get chance to throw an example together this morning.
Steven Robbins
A: 

First of all, many thanks to Steve Robins for getting me started down the right track. My approach was slightly different, partial due to the fact I was not using a DataBind method.

I use a combination of the OnRowDataBound and OnDataBound events of the DataView. The OnRowDataBound event to determine the index of the row to be put into edit mode. The OnDataBound event sets the index and rebinds the DataView.

A variable is used to ensure that the View is not continuously rebound.

Here is the crux of the aspx page edited down for brevity.

<asp:GridView ID="GridView1" runat="server" 
              DataSourceID="CreativeTypeDS"
              AutoGenerateColumns="False" 
              DataKeyNames="SourceCreativeTypeID" 
              EmptyDataText="No Cretive Types at this time."
              CellPadding="3" CellSpacing="1"
              OnRowDataBound="GridView1_RowDataBound"
              OnDataBound="GridView1_DataBound" >
        <Columns>
           [Template Columns Here]
        </Columns>
</asp:GridView>

<asp:SqlDataSource ID="CreativeTypeDS" runat="server" 
                   SelectCommand="cmsSourceCreativeTypeSel"
                   SelectCommandType="StoredProcedure" 
        UpdateCommand="cmsSourceCreativeTypeUpd"
                   UpdateCommandType="StoredProcedure">
    <SelectParameters>                
       <asp:Parameter Name="Active" DefaultValue="0" />
    </SelectParameters>
    <UpdateParameters>
       <asp:Parameter Name="SourceCreativeTypeID" Type="Int32" />
       <asp:Parameter Name="SourceCategoryID" Type="Int32"/>
       <asp:Parameter Name="Name" Type="String" />
       <asp:Parameter Name="Active" Type="Boolean" />
     </UpdateParameters>
</asp:SqlDataSource>

And now for the code behind.

 public partial class SourceCreativeTypes : System.Web.UI.Page
 {
    private int? EditIndex = null;
    private bool GridRebound = false;
    protected override void OnPreInit(EventArgs e)        
    {
       CreativeTypeDS.ConnectionString = "[CONNECTION STRING MAGIC HERE]";
    }

    protected void Page_Load(object sender, EventArgs e)
    {
        if (IsPostBack)
        {                
            //Dont Want to set edit row manualy if post back
            GridRebound = true;
        }
    }

    //Use the Row Databound Event to find the row to put into edit mode 
    protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
    {
        if (!String.IsNullOrEmpty(Request.QueryString["ID"]))
        {
            //Get Target ID from Query String
            string sSourceCreativeTypeID = Request.QueryString["ID"];
            //Get data for row being bound
            DataRowView rowView = (DataRowView)e.Row.DataItem;

            // Set index if we are in a "normal row", the row data 
            // has been retrieved
            // and the Supplied ID matches that of this row
            if ((e.Row.RowState == DataControlRowState.Normal || 
                e.Row.RowState == DataControlRowState.Alternate) 
                &&
                (rowView != null && 
                 rowView["SourceCreativeTypeID"].ToString() == sSourceCreativeTypeID)
                )
            {                   
                EditIndex = e.Row.RowIndex;                   
            }
        }
    }

    /* Use the Datbound Event to set the required row to index mode
     * Then Rebind the grid. Rebinding in Row Databound does not work
     * for Reasons unknown */
    protected void GridView1_DataBound(object sender, EventArgs e)
    {
        //Set Gridview edit index if one is supplied and page is not a post back
        if (!GridRebound && EditIndex != null)
        {
            //Setting GridRebound ensures this only happens once
            GridRebound = true;
            GridView1.EditIndex = (int)EditIndex;
            GridView1.DataBind();
        }
     }
   } 
}

Hopefully between Steve and Myself we help a few of you out there

Jon P
A: 

Thank you! It helped me a lot. Just one question, what if the grid view has paging enabled and the row I want to edit resides in other pages (1,2,3,...,4,5,6).

Good question!! So good I would say it deserves to be it's own question, particularly as a quick answer is not springing to mind. Feel free to reference this question as part of yours. I'll still see if I can come up with something.
Jon P
A: 

Thanx for insight. What if I need to bind one column only for a bound gridview to values in a text box.