2010-01-07 123 views
0

我一直在使用GridViews和DetailsViews很長一段時間,但是昨天我遇到了一個新的場景,我很不明白。我有一個GridView與ImageButton(CommandName =「插入」),這將改變DetailsView的模式插入。之後我會在DetailsView中查找DropDownList並動態添加一些項目。工作正常,但首先我第一次按下ImageButton。如果我在DetailsView中單擊「取消」並再次按下ImageButton,則.FindControl()方法返回null。我在這裏面臨什麼樣的生命週期問題?DetailsView 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生成,並且將模式更改爲InsertMode不會影響呈現的標記,或者類似的東西。

有沒有人有解決這個問題? =)

回答

2

我認爲你是在正確的軌道上。很難說沒有看到所有的代碼,但基本上每當你改變一箇中繼器類型控制中的行的渲染模式時,你需要重新綁定它以便重新渲染。 FindControl返回NULL的事實意味着只有一件事:控制不在那裏。這意味着它沒有呈現。您可以通過查看控制層次來驗證這一點。

那麼,在您的處理程序取消你重新綁定?

+0

我上面發佈的代碼足以重現所描述的情況。我會嘗試查看一些額外的.DataBinds()是否可以工作。 – citronas 2010-01-07 03:02:19

+1

更改模式後顯式dvCategory.DataBind()帶來了解決方案。謝謝你,你不知道我在這工作了多長時間;) 你有沒有機會知道.DataBind()調用到底做了什麼?它爲什麼有效?它是否強制DetailsView生成新的標記? – citronas 2010-01-07 03:04:41

+0

好吧,現在你問的是棘手的問題......老實說,並不完全確定,但這裏是我的看法:我不認爲有任何標記正在渲染,但是這個調用觸發了實際控制層次的創建。對於模板控件,一次只創建一個模板:您可以具有ItemTemplate或EditTemplate,但不能同時擁有兩個模板。那麼爲什麼這個工作的第一個電話?不確定。 – Bryan 2010-01-07 20:33:46