DetailsView FindControl()在一些回发后返回null

时间:2010-01-07 00:41:31

标签: c# asp.net gridview postback detailsview

我已经使用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不会影响渲染的标记,或类似的东西。

有人有解决方法吗? =)

1 个答案:

答案 0 :(得分:2)

我认为你走在正确的轨道上。在没有看到所有代码的情况下很难分辨,但基本上每当你在转发器类型控件中更改行的渲染模式时,你需要重新绑定它以便重新渲染它。 FindControl返回NULL的事实只意味着一件事:控件不在那里。这意味着它没有呈现。您可以通过查看控件层次结构来验证这一点。

那么,你在Cancel的处理程序中重新绑定了吗?