我试图在绑定到LinqDataSource的ASP.NET 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>
正如您在第二列(Division)中看到的,我正在使用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 :(得分:0)
您正在调用cboBusinessUnit.DataBind();在向您的下拉列表分配任何数据之前,需要在调用DataBind()之前设置DataSource
cboBusinessUnit.DataSource = ?
但是从错误中我也说你的GridView可能在回发时变得不受约束。也许如果我们有你的Page_Load方法和DataBinding方法,我们可以告诉你更多。
更新。 是的确没有读过数据源,只是没有把它拿进来!!所以当事情绑定等时仍然会看到
答案 1 :(得分:0)
试试这个
protected void cboDivision_SelectedIndexChanged(object sender, EventArgs e)
{
cboBusinessUnit.DataSource= gvAreas.Rows[gvAreas.EditIndex].FindControl("cboBusinessUnit") as DropDownList;
cboBusinessUnit.DataBind();
}
答案 2 :(得分: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;
}
}
}