0

我已经使用 GridViews 和 DetailsViews 工作了很长时间,但是昨天我遇到了一个新场景,我很不明白。

我有一个带有 ImageButton (CommandName="Insert") 的 GridView,它会将 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 不会影响呈现的标记或类似的东西。

有人对此有解决方案吗?=)

4

1 回答 1

2

我认为你在正确的轨道上。如果不查看所有代码很难判断,但基本上任何时候您更改中继器类型控件中一行的渲染模式时,您都需要重新绑定它以便重新渲染它。FindControl 返回 NULL 的事实仅意味着一件事:控件不存在。这意味着它没有被渲染。您可以通过查看控制层次结构来验证这一点。

那么,在您的 Cancel 处理程序中,您是否重新绑定?

于 2010-01-07T02:58:28.083 回答