使用选定值(隐藏列)填充数据库的下拉列表

时间:2017-05-03 18:10:06

标签: c# asp.net data-binding dropdown

我有一个控件在不同的页面上使用,但在一个特定的页面上,我有一个下拉列表,让用户可以更改数据库中的某个字段。下拉列表有两个项目(“出勤日”和“出勤日”),我希望在访问控件时加载数据库中的任何选项。

以下是我的网格视图的顶部:

<asp:GridView runat="server" DataSourceID="sdsLookups" ID="gvValues" 
AutoGenerateColumns="False" Width="760px" OnDataBound ="GridView_DataBound">

以下是网格视图中的实际下拉列表。在正确的页面上,正在从数据库加载正确的值:

<asp:TemplateField HeaderText="Is Attendance?">
    <ItemTemplate>
        <asp:DropDownList id="ddlAttendanceStatus"  AutoPostBack="True" runat ="server" SelectedValue='<%# Eval("rules") %>' >
            <asp:ListItem>Attendance Day</asp:ListItem>
            <asp:ListItem>Not Attendance Day</asp:ListItem>
        </asp:DropDownList>
    </ItemTemplate>
</asp:TemplateField>

这是我目前用来隐藏列的代码。我也试图检查项目是否为空,但我还没有工作:

protected void GridView_DataBound(object sender, EventArgs e)
{
    if (this.LookupType == "Day Status" ? true : false)
    {
        gvValues.Columns[12].Visible = true;
        GridViewRow row = (sender as Control).Parent.Parent as GridViewRow;
        DropDownList rules = (row.FindControl("ddlAttendanceStatus") as DropDownList);
        ListItem item = rules.Items.FindByText("Attendance Day");
        if (item != null)
            rules.Items.FindByText("Attendance Day").Selected = true;
    }
}

目前,该列仅出现在正确的页面上,但当我转到使用此控件的其他页面时,我收到一条错误消息:

ArgumentOutOfRangeException: 'ddlAttendanceStatus' has a SelectedValue which is invalid because it does not exist in the list of items. Parameter name: value

我知道为什么我会收到此错误,但我不确定如何解决这个问题。如果我没有在正确的页面上,有没有办法完全忽略这个字段?或者我应该采取不同的路线?

如果我需要发布更多信息,请与我们联系。

提前谢谢。

1 个答案:

答案 0 :(得分:0)

问题是aspx页面上的这段代码:SelectedValue='<%# Eval("rules") %>'。在其他页面中,如果rules不存在或者值不是Attendance DayNot Attendance Day,您将收到该错误。您可以通过在SelectedValue事件中设置OnRowDataBound来解决此问题。

首先将aspx上的GridView更改为

<asp:GridView runat="server" DataSourceID="sdsLookups" ID="gvValues" 
    AutoGenerateColumns="False" Width="760px" OnDataBound="GridView_DataBound" 
    OnRowDataBound="gvValues_RowDataBound">

然后在代码背后

protected void gvValues_RowDataBound(object sender, GridViewRowEventArgs e)
{
    //check if the row is a datarow
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
        //cast the row back to a datarowview
        DataRowView row = e.Row.DataItem as DataRowView;

        //find the dropdownlist with findcontrol
        DropDownList rules = e.Row.FindControl("ddlAttendanceStatus") as DropDownList;

        if (row["myColumn"].ToString() == "Day Status")
        {
            //set the correct selectedvalue
            rules.SelectedValue = "Not Attendance Day";

            //or
            rules.SelectedValue = "1";
        }
    }
}

最后作为一个选项,我建议你使用Key / Values作为ListItems。这样可以更轻松地处理长字符串。

<asp:DropDownList ID="ddlAttendanceStatus" AutoPostBack="True" runat="server">
    <asp:ListItem Text="Attendance Day" Value="0"></asp:ListItem>
    <asp:ListItem Text="Not Attendance Day" Value="1"></asp:ListItem>
</asp:DropDownList>

<强>更新

首先从GridView本身移除DataSourceID并将其移到后面的代码中。

if (!Page.IsPostBack)
{
    GridView1.DataSource = yourSource;
    GridView1.DataBind();
}

你在DropDownList上将AutoPostBack设置为True,但似乎没有处理PostBack。如果没有发生任何事情,请尝试删除它。要编辑和更新网格内的数据,请查看this tutorial。它涵盖了所有基础知识。