2014-03-06 99 views
1

我想鏈接一些綁定到LinqDataSource的ASP.NET gridview控件下拉列表。當我點擊'編輯'命令字段時,下拉框會按照它們應該顯示的內容顯示。當用戶更改第一個下拉菜單時,我想根據第一個下拉菜單的選擇重新填充第二個下拉菜單。這是我的GridView:gridview中的鏈接下拉列表

<asp:GridView ID="gvAreas" runat="server" AllowSorting="True" AutoGenerateColumns="False" CssClass="grid pad5 full" DataKeyNames="ID" DataSourceID="ldsAreas"> 
    <Columns> 
     <asp:BoundField DataField="ID" HeaderText="ID" InsertVisible="False" ReadOnly="True" SortExpression="ID" Visible="false" /> 
     <asp:TemplateField HeaderText="Division" SortExpression="CDB_BusinessUnit.CDB_Division.Name"> 
      <ItemTemplate> 
       <%#Eval("CDB_BusinessUnit.CDB_Division.Name") %> 
      </ItemTemplate> 
      <EditItemTemplate> 
       <asp:DropDownList ID="cboDivision" runat="server" AppendDataBoundItems="True" DataSourceID="ldsDivisions" DataTextField="Name" DataValueField="ID" SelectedValue='<%#Eval("CDB_BusinessUnit.DivisionID") %>' AutoPostBack="True" OnSelectedIndexChanged="cboDivision_SelectedIndexChanged"> 
        <asp:ListItem Text="" Value="" /> 
       </asp:DropDownList> 
       <asp:LinqDataSource ID="ldsDivisions" runat="server" ContextTypeName="CommonDB_Management.CommonDBDataContext" EntityTypeName="" Select="new (ID, Name)" TableName="CDB_Divisions" OrderBy="Name" /> 
      </EditItemTemplate> 
     </asp:TemplateField> 
     <asp:TemplateField HeaderText="Business Unit" SortExpression="CDB_BusinessUnit.Name"> 
      <ItemTemplate> 
       <%#Eval("CDB_BusinessUnit.Name") %> 
      </ItemTemplate> 
      <EditItemTemplate> 
       <asp:DropDownList ID="cboBusinessUnit" runat="server" AppendDataBoundItems="true" DataSourceID="ldsBusinessUnits" DataTextField="Name" DataValueField="ID" SelectedValue='<%#Bind("BusinessUnitID") %>' /> 
       <asp:LinqDataSource ID="ldsBusinessUnits" runat="server" ContextTypeName="CommonDB_Management.CommonDBDataContext" EntityTypeName="" TableName="CDB_BusinessUnits" Where="DivisionID == @DivisionID" > 
        <WhereParameters> 
         <asp:ControlParameter ControlID="cboDivision" Name="DivisionID" PropertyName="SelectedValue" Type="Int32" /> 
        </WhereParameters> 
       </asp:LinqDataSource> 
      </EditItemTemplate> 
     </asp:TemplateField> 
     <asp:CommandField ShowEditButton="true" HeaderStyle-Width="100px" HeaderStyle-CssClass="center" ItemStyle-CssClass="center" HeaderText="Edit" ValidationGroup="gv" /> 
     <asp:CommandField ShowDeleteButton="true" HeaderStyle-Width="100px" HeaderStyle-CssClass="center" ItemStyle-CssClass="center" HeaderText="Delete" /> 
    </Columns> 
</asp:GridView> 

<asp:LinqDataSource ID="ldsAreas" runat="server" ContextTypeName="CommonDB_Management.CommonDBDataContext" EnableDelete="True" EnableInsert="True" EnableUpdate="True" EntityTypeName="" TableName="CDB_Areas" OrderBy="CDB_BusinessUnit.CDB_Division.Name, CDB_BusinessUnit.Name, Name"></asp:LinqDataSource> 

正如你可以在第二列(司),我現在用的是OnSelectedIndexChanged事件來試試,看看重新綁定第二個下拉列表。下面是該事件中的代碼:

protected void cboDivision_SelectedIndexChanged(object sender, EventArgs e) 
{ 
    DropDownList cboBusinessUnit = gvAreas.Rows[gvAreas.EditIndex].FindControl("cboBusinessUnit") as DropDownList; 
    cboBusinessUnit.DataBind(); 
} 

我的問題是,上面的代碼炸燬的DataBind()電話與消息:

Databinding methods such as Eval(), XPath(), and Bind() can only be used in the context of a databound control.

控制cboBusinessUnit顯然綁定到的LinqDataSource那存在於它下面。爲什麼我會收到此消息,以及有關如何正確執行此操作的任何建議?

+0

爲什麼你必須到現場的SelectedValue綁定您cboBusinessUnit下拉列表?如果你把它拿出來怎麼辦? –

+0

用戶需要能夠保存記錄的BusinessUnitID。如果我刪除了SelectedValue,那麼他們將無法更新業務單位(並且它不會爲記錄顯示正確的業務單位)。 – Hoff

+0

它確實擺脫了錯誤,雖然當我刪除...所以,也許我必須在代碼隱藏後手動設置BusinessUnitID ... – Hoff

回答

0

嗯,我不能讓它正常工作使用DropDownList的SelectedValue屬性和使用LinqDataSource ControlParameter,所以我不得不做的幾乎一切代碼隱藏。以下是我結束了:

<asp:GridView ID="gvAreas" runat="server" AllowSorting="True" AutoGenerateColumns="False" CssClass="grid pad5 full" DataKeyNames="ID" DataSourceID="ldsAreas" OnRowUpdating="gvAreas_RowUpdating" OnRowDataBound="gvAreas_RowDataBound"> 
    <Columns> 
     <asp:BoundField DataField="ID" HeaderText="ID" InsertVisible="False" ReadOnly="True" SortExpression="ID" Visible="false" /> 
     <asp:TemplateField HeaderText="Division" SortExpression="CDB_BusinessUnit.CDB_Division.Name"> 
      <ItemTemplate> 
       <%#Eval("CDB_BusinessUnit.CDB_Division.Name") %> 
      </ItemTemplate> 
      <EditItemTemplate> 
       <asp:DropDownList ID="cboDivision" runat="server" DataSourceID="ldsDivisions" DataTextField="Name" DataValueField="ID" AutoPostBack="True" OnSelectedIndexChanged="cboDivision_SelectedIndexChanged" AppendDataBoundItems="true"> 
        <asp:ListItem Value="" Text="" /> 
       </asp:DropDownList> 
       <asp:LinqDataSource ID="ldsDivisions" runat="server" ContextTypeName="CommonDB_Management.CommonDBDataContext" EntityTypeName="" Select="new (ID, Name)" TableName="CDB_Divisions" OrderBy="Name" /> 
      </EditItemTemplate> 
     </asp:TemplateField> 
     <asp:TemplateField HeaderText="Business Unit" SortExpression="CDB_BusinessUnit.Name"> 
      <ItemTemplate> 
       <%#Eval("CDB_BusinessUnit.Name") %> 
      </ItemTemplate> 
      <EditItemTemplate> 
       <asp:DropDownList ID="cboBusinessUnit" runat="server" DataTextField="Name" DataValueField="ID" /> 
      </EditItemTemplate> 
     </asp:TemplateField> 
     <asp:CommandField ShowEditButton="true" HeaderStyle-Width="100px" HeaderStyle-CssClass="center" ItemStyle-CssClass="center" HeaderText="Edit" ValidationGroup="gv" /> 
     <asp:CommandField ShowDeleteButton="true" HeaderStyle-Width="100px" HeaderStyle-CssClass="center" ItemStyle-CssClass="center" HeaderText="Delete" /> 
    </Columns> 
</asp:GridView> 

代碼隱藏:

protected void cboDivision_SelectedIndexChanged(object sender, EventArgs e) 
{ 
    DropDownList cboDivision = gvAreas.Rows[gvAreas.EditIndex].FindControl("cboDivision") as DropDownList; 
    DropDownList cboBusinessUnit = gvAreas.Rows[gvAreas.EditIndex].FindControl("cboBusinessUnit") as DropDownList; 

    cboBusinessUnit.Items.Clear(); 

    if (cboDivision.SelectedValue != null && !String.IsNullOrEmpty(cboDivision.SelectedValue)) 
    { 
     var businessUnits = db.CDB_BusinessUnits.Where(b => b.DivisionID == Convert.ToInt32(cboDivision.SelectedValue)).OrderBy(b => b.Name); 
     cboBusinessUnit.DataSource = businessUnits; 
    } 
    else 
    { 
     var businessUnits = db.CDB_BusinessUnits.Where(b => b.DivisionID == null).OrderBy(b => b.Name); 
     cboBusinessUnit.DataSource = businessUnits; 
    } 

    cboBusinessUnit.DataBind(); 
} 

protected void gvAreas_RowUpdating(object sender, GridViewUpdateEventArgs e) 
{ 
    DropDownList cboBusinessUnit = gvAreas.Rows[gvAreas.EditIndex].FindControl("cboBusinessUnit") as DropDownList; 

    if (cboBusinessUnit.SelectedValue != null && !String.IsNullOrEmpty(cboBusinessUnit.SelectedValue)) 
    { 
     e.NewValues["BusinessUnitID"] = Convert.ToInt32(cboBusinessUnit.SelectedValue); 
    } 
    else 
    { 
     e.NewValues["BusinessUnitID"] = null; 
    } 
} 

protected void gvAreas_RowDataBound(object sender, GridViewRowEventArgs e) 
{ 
    if ((e.Row.RowState & DataControlRowState.Edit) > 0) 
    { 
     CDB_Area area = e.Row.DataItem as CDB_Area; 

     if (area.BusinessUnitID != null) 
     { 
      DropDownList cboDivision = e.Row.FindControl("cboDivision") as DropDownList; 
      DropDownList cboBusinessUnit = e.Row.FindControl("cboBusinessUnit") as DropDownList; 

      if (area.CDB_BusinessUnit.DivisionID != null) 
      { 
       cboDivision.Items.FindByValue(area.CDB_BusinessUnit.DivisionID.ToString()).Selected = true; 

       var businessUnits = db.CDB_BusinessUnits.Where(b => b.DivisionID == area.CDB_BusinessUnit.DivisionID).OrderBy(b => b.Name); 
       cboBusinessUnit.DataSource = businessUnits; 
      } 
      else 
      { 
       var businessUnits = db.CDB_BusinessUnits.Where(b => b.DivisionID == null).OrderBy(b => b.Name); 
       cboBusinessUnit.DataSource = businessUnits; 
      } 

      cboBusinessUnit.DataBind(); 
      cboBusinessUnit.Items.FindByValue(area.BusinessUnitID.ToString()).Selected = true; 
     } 
    } 
} 
0

您正在調用cboBusinessUnit.DataBind();上的任何數據分配給它的數據源之前,你的下拉列表需要調用的DataBind()之前設置

cboBusinessUnit.DataSource = ? 

而且從錯誤我說你的GridView可能會成爲在回發綁定。也許如果我們有你的Page_Load方法和DataBinding方法,我們可以告訴你更多。

更新。 是啊讀過關於數據源,只是沒有把它放在!所以仍然會看時,事情結合等

+0

下拉列表的數據源未在代碼隱藏中設置,它綁定到GridView自身中存在的LinqDataSource 。代碼隱藏中唯一的代碼顯示在問題中('cboDivision_SelectedIndexChanged')。但是你可能是對的,這可能是一個訂單問題,事件在數據源被綁定之前被解僱。 – Hoff

+0

想通了,但獎勵你的賞金,所以它不會浪費,你的答案是最接近的。感謝您看看它。 – Hoff

0

試試這個

protected void cboDivision_SelectedIndexChanged(object sender, EventArgs e) 
{ 
cboBusinessUnit.DataSource= gvAreas.Rows[gvAreas.EditIndex].FindControl("cboBusinessUnit") as DropDownList; 

cboBusinessUnit.DataBind(); 
} 
+0

數據源是作爲控件的一個屬性提供的,爲什麼我必須再次提供它? 'DataSourceID =「ldsBusinessUnits」DataTextField =「Name」DataValueField =「ID」' – Hoff

+0

我們不能直接綁定下拉列表而不提供數據源。我的理解是,您嘗試重新綁定第二個列表(更改列表項),這是基於第一個列表的選擇,因此爲了做到這一點,您必須重新綁定與數據源一起提供的第二個列表,然後重新綁定列表。 – Dextere

+0

提供了數據源:'DataSourceID =「ldsBusinessUnits」' – Hoff