简体   繁体   English

ASP.NET GridView 不显示下拉列表

[英]ASP.NET GridView Not Displaying DropDownList

I have an ASP.NET web app that connects to a SQL database and populates several gridviews on one page, showing different sets of data.我有一个 ASP.NET web 应用程序,它连接到 SQL 数据库并在一个页面上填充多个网格视图,显示不同的数据集。 Two of the columns are drop downs as I want the user to be able to select a different (category and status).其中两列是下拉列表,因为我希望用户能够 select 不同(类别和状态)。 The only way I can get the data to display is if I hard code the category and status names in the gridview itself like this:我可以让数据显示的唯一方法是,如果我在 gridview 本身中硬编码类别和状态名称,如下所示:

<asp:TemplateField SortExpression="rank" Visible="true" HeaderText="Area" >
    <HeaderStyle HorizontalAlign="Left" CssClass="col_med" />
    <ItemTemplate>
    <asp:DropDownList id="ddlRank" AutoPostBack="True" OnSelectedIndexChanged="Rank_Change" runat="server" CssClass="col_med" 
    SelectedValue='<%# Eval("rank") %>' TabIndex='<%# TabIndex %>'>
        <asp:ListItem Value=""> - </asp:ListItem>
        <asp:ListItem Value="1"> 1</asp:ListItem>
        <asp:ListItem Value="2"> 2</asp:ListItem>
        <asp:ListItem Value="3"> 3</asp:ListItem>
        <asp:ListItem Value="4"> 4</asp:ListItem>
        <asp:ListItem Value="5"> 5</asp:ListItem>
        <asp:ListItem Value="6"> 6</asp:ListItem>
    </asp:DropDownList>
    </ItemTemplate>
</asp:TemplateField>

What I want to do is pull the statuses from the database and display them in my gridview using the我想要做的是从数据库中提取状态并使用

OnRowDataBound="OnRowDataBound"

Pulling the data from the database into the dropdownlists like this:将数据库中的数据拉到下拉列表中,如下所示:

protected void OnRowDataBound(object sender, GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
        //Find the DropDownList in the Row
        DataTable ddLine = DAL.listLine();
        ddLine = resort(ddLine, "line", "desc");
        //Find the DropDownList in the Row
        DataTable ddlArea = DAL.listArea();
        ddlArea = resort(ddlArea, "area", "desc");
    }
}

However this is not working and no data displays in my gridview at all when I try to implement OnRowDataBound and change my gridview like this:但是,这不起作用,当我尝试实现OnRowDataBound并像这样更改我的 gridview 时,我的 gridview 中根本没有数据显示:

<asp:BoundField HeaderText="Area" DataField="rank" />
    <asp:TemplateField HeaderText = "Area">
        <ItemTemplate>
            <asp:Label ID="lblArea" runat="server" Text='<%# Eval("rank") %>' Visible = "false" />
            <asp:DropDownList ID="ddlArea" runat="server">
            </asp:DropDownList>
        </ItemTemplate>
    </asp:TemplateField>

Can anyone advise if the above approach is best practices for my scenario and if so, what could be wrong with the code resulting in my data not showing up?任何人都可以建议上述方法是否是我的方案的最佳实践,如果是,代码可能有什么问题导致我的数据不显示?

Ok, since a dropdown in each row?好的,因为每一行都有一个下拉菜单? Two issues: One, you have to fill it in the item data bound event.两个问题:一、必须在item数据绑定事件中填写。 Two, you ALSO have to then set the value to the correct value.二,您还必须将值设置为正确的值。

So, you need to do both goals.所以,你需要同时实现这两个目标。

And lets toss in the ability to tab around on each row, edit the values, and then have ONE save button.并让我们能够在每一行上进行选项卡,编辑值,然后有一个保存按钮。 You can dump the save button, but say we have a city drop down list in that gridview.您可以转储保存按钮,但假设我们在 gridview 中有一个城市下拉列表。 So we have this markup (and city will be the dropdown list).所以我们有这个标记(城市将是下拉列表)。

So, our markup is this:所以,我们的标记是这样的:

<div style="width:40%">

  <asp:GridView ID="MyGrid" runat="server" AutoGenerateColumns="false" CssClass="table table-hover">

    <Columns>
        <asp:TemplateField HeaderText ="First Name">
            <ItemTemplate> <asp:TextBox ID="FirstName" runat="server" Text='<%# Eval("FirstName") %>'></asp:TextBox></ItemTemplate>
        </asp:TemplateField>

        <asp:TemplateField HeaderText ="Last Name">
            <ItemTemplate><asp:TextBox ID="LastName" runat="server" Text='<%# Eval("LastName") %>'></asp:TextBox></ItemTemplate>
        </asp:TemplateField>

        <asp:TemplateField HeaderText ="Hotel Name">
            <ItemTemplate><asp:TextBox ID="HotelName" runat="server" Text='<%# Eval("HotelName") %>'></asp:TextBox></ItemTemplate>
        </asp:TemplateField>


        <asp:TemplateField HeaderText ="City">
            <ItemTemplate>
            <asp:DropDownList  id="CityDrop" runat="server" datatextfield="City" datavaluefield="City" style="height:25px" ></asp:DropDownList>
            </ItemTemplate>
        </asp:TemplateField>

        <asp:Templatefield HeaderText ="Province">
            <ItemTemplate><asp:TextBox ID="Province" runat="server" Text='<%# Eval("Province") %>' ></asp:TextBox></ItemTemplate>
        </asp:Templatefield>
        
    </Columns>

  </asp:GridView>

<asp:Button ID="cmdSave" runat="server" Text="Save Edits" Width="124px" />
</div>

Ok, so the output looks like this:好的,所以 output 看起来像这样:

在此处输入图像描述

So you can tab around - make changes.因此,您可以使用标签 - 进行更改。 And then the one save button will write all changes back to the database.然后一个保存按钮会将所有更改写回数据库。

You can remove the database save button code - but it not much code anyway.您可以删除数据库保存按钮代码 - 但无论如何代码并不多。

And I DID persist the table - that just saved code.而且我确实保留了表格 - 刚刚保存了代码。 As noted, you can remove the persisting of the table if you don't want edits (dump the view state code).如前所述,如果您不想编辑,可以删除表的持久化(转储视图 state 代码)。

As for the city combo box?至于城市组合框? I only load the city table one time - and only on the first page load - it persists JUST long enough at the form level for the item databound code to work.我只加载一次城市表 - 并且仅在第一页加载时 - 它在表单级别持续足够长的时间,以便项目数据绑定代码工作。

The code that binds the combo box ALSO adds a blank row - since I wanted to allow a blank selection.绑定组合框的代码还添加了一个空白行 - 因为我想允许空白选择。

The code is thus this:因此代码是这样的:

    DataTable MyTable = new DataTable();
    DataTable MyCity = new DataTable();

    protected void Page_Load(object sender, EventArgs e)
    {
        if (IsPostBack == false)
        {
            LoadGrid();
            ViewState["MyTable"] = MyTable;
        }
        else
                MyTable = (DataTable)ViewState["MyTable"];
    }

    public void LoadGrid()
    {
        using (SqlCommand cmdSQL = new SqlCommand("SELECT City from tblCity ORDER BY City",
            new SqlConnection(Properties.Settings.Default.TEST3)))
        {
            cmdSQL.Connection.Open();
            MyCity.Load(cmdSQL.ExecuteReader());


            cmdSQL.CommandText = "SELECT * from tblHotels ORDER BY HotelName";
            MyTable.Load(cmdSQL.ExecuteReader());
            MyGrid.DataSource = MyTable;
            MyGrid.DataBind();

        }
    }

    protected void MyGrid_RowDataBound(object sender, GridViewRowEventArgs e)
    {
        if (e.Row.RowType == DataControlRowType.DataRow)
        {
            DropDownList mydrop = (DropDownList)e.Row.FindControl("CityDrop");
            mydrop.DataSource = MyCity;
            mydrop.DataBind();
            mydrop.Items.Insert(0, new ListItem(string.Empty));     // add blank row
                                                                    // set drop down list to row value (use table to get this value)
            
            mydrop.Text = MyTable.Rows[e.Row.RowIndex]["City"].ToString();
        }
    }

    protected void cmdSave_Click(object sender, EventArgs e)
    {
        // move data from grid to table
        foreach (GridViewRow MyRowG in MyGrid.Rows)
        {
            DataRow OneRow = MyTable.Rows[MyRowG.RowIndex];
            TextBox tt;
            
            OneRow["FirstName"] = ((TextBox)MyRowG.FindControl("FirstName")).Text;
            OneRow["lastName"] = ((TextBox)MyRowG.FindControl("LastName")).Text;
            OneRow["HotelName"] = ((TextBox)MyRowG.FindControl("HotelName")).Text;
            OneRow["City"] = ((DropDownList)MyRowG.FindControl("CityDrop")).Text;
            OneRow["Province"] = ((TextBox)MyRowG.FindControl("Province")).Text;
        }

        // table now loaded - save back to databsse
        using (SqlCommand cmdSQL = new SqlCommand("SELECT * from tblHotels WHERE ID = 0",
                                   new SqlConnection(Properties.Settings.Default.TEST3)))
        {
            SqlDataAdapter da = new SqlDataAdapter(cmdSQL);
            SqlCommandBuilder daUpdate = new SqlCommandBuilder(da);

            da.Update(MyTable);
        }
    }
}

So, you have to load up each drop down list for each row, then set the value of that dropdown list to the correct value (you have to do both).因此,您必须为每一行加载每个下拉列表,然后将该下拉列表的值设置为正确的值(您必须两者都做)。

As noted, if your goal is to not have the user tab around, make changes - select the drop down etc?如前所述,如果您的目标是不使用用户选项卡,请进行更改 - select 下拉等? Then you can dump the save button code, and dump the viewstate code that persists the data table.然后您可以转储保存按钮代码,并转储持久化数据表的视图状态代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM