Question

I've been working for a long time with GridViews and DetailsViews, but yesterday I've come across a new scenario, which I quite do not understand.

I have a GridView with ImageButton (CommandName="Insert") which will change the mode of the DetailsView to Insert. Afterwards I'll look for a DropDownList inside that DetailsView and add some items dynamically. Works fine, but one first the first time I press that ImageButton. If I click on "Cancel" in the DetailsView and press the ImageButton again, the .FindControl() Method returns null. What life cycle problem am I facing here?

I've created this sample: (To make it run in your Visual Studio, just bind a DataSource to the DetailsView, otherwise it will not be rendered)

Markup:

<asp:GridView ID="gvCategory" runat="server" OnRowCommand="gvCategory_RowCommand">
    <Columns>
    </Columns>
    <EmptyDataTemplate>
        <asp:ImageButton ImageUrl="~/images/add.png" ID="ibAdd" runat="server" CommandName="Insert" />
    </EmptyDataTemplate>
    </asp:GridView>
    <asp:DetailsView ID="dvCategory" runat="server" Width="150px" AutoGenerateRows="false"
           AutoGenerateInsertButton="True" DataSourceID="LinqDataSource1">
    <Fields>
        <asp:TemplateField HeaderText="foo">
            <InsertItemTemplate>
                <asp:DropDownList ID="ddlCategory" runat="server" Width="150"></asp:DropDownList>
            </InsertItemTemplate>
        </asp:TemplateField>
    </Fields>
    </asp:DetailsView><asp:LinqDataSource ID="LinqDataSource1" runat="server" 
    ContextTypeName="WebApplication1.DataClasses1DataContext" 
    TableName="Categories"></asp:LinqDataSource>

Codebehind:

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

    }

    protected void gvCategory_RowCommand(object sender, GridViewCommandEventArgs e)
    {
        if (e.CommandName == "Insert")
        {
            this.dvCategory.ChangeMode(DetailsViewMode.Insert);
            DropDownList _ddlCat = (DropDownList)this.dvCategory.FindControl("ddlCategory");
            if (_ddlCat != null)
            {
                _ddlCat.Items.Clear();
                _ddlCat.Items.Add(new ListItem() { Text = "-- empty --", Value = "-1" });
            }
        }
   }

I have also tried using a ItemTemplate, and not a InsertItemTemplate, but this results in the same. After using the ChangeMode-Method the DetailsView.CurrentMode == InsertMode. The only thing I can think of is, that the markup is already generated for the ItemTemplate and changing the Mode to InsertMode can't affect the rendered markup, or something like this.

Does anybody have a solution to this? =)

Was it helpful?

Solution

I think you are on the right track. It's hard to tell without seeing all of the code, but basically any time you change the rendering mode of a row in a repeater-type control you need to rebind it so that it's re-rendered. The fact that FindControl is returning NULL means only one thing: THE CONTROL IS NOT THERE. Which means it was not rendered. You can verify this by looking at the control hierarchy.

So, in your handler for Cancel are you rebinding?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top