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? =)