我已经使用GridViews和DetailsViews工作了很长时间,但昨天我遇到了一个新的场景,我完全不明白。
我有一个带有ImageButton的GridView(CommandName =“Insert”),它会将DetailsView的模式更改为Insert。之后我将在DetailsView中查找DropDownList并动态添加一些项目。工作正常,但我第一次按下那个ImageButton。如果我在DetailsView中单击“取消”并再次按下ImageButton,则.FindControl()方法返回null。我面临的生命周期问题是什么?
我已创建此示例:(要使其在Visual Studio中运行,只需将DataSource绑定到DetailsView,否则将无法呈现)
标记:
<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>
代码隐藏:
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" });
}
}
}
我也尝试过使用ItemTemplate,而不是使用InsertItemTemplate,但结果却相同。使用ChangeMode-Method后,DetailsView.CurrentMode == InsertMode。我唯一能想到的是,已经为ItemTemplate生成了标记,并且将Mode更改为InsertMode不会影响渲染的标记,或类似的东西。
有人有解决方法吗? =)
答案 0 :(得分:2)
我认为你走在正确的轨道上。在没有看到所有代码的情况下很难分辨,但基本上每当你在转发器类型控件中更改行的渲染模式时,你需要重新绑定它以便重新渲染它。 FindControl返回NULL的事实只意味着一件事:控件不在那里。这意味着它没有呈现。您可以通过查看控件层次结构来验证这一点。
那么,你在Cancel的处理程序中重新绑定了吗?