c# - ASP.NET GridView 不显示下拉列表
问题描述
我有一个 ASP.NET Web 应用程序,它连接到 SQL 数据库并在一个页面上填充多个网格视图,显示不同的数据集。其中两列是下拉列表,因为我希望用户能够选择不同的(类别和状态)。我可以让数据显示的唯一方法是,如果我在 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>
我想要做的是从数据库中提取状态并使用
OnRowDataBound="OnRowDataBound"
将数据库中的数据拉到下拉列表中,如下所示:
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");
}
}
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>
任何人都可以建议上述方法是否是我的方案的最佳实践,如果是,代码可能有什么问题导致我的数据不显示?
解决方案
Ok, since a dropdown in each row? Two issues: One, you have to fill it in the item data bound event. 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. 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:
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).
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? Then you can dump the save button code, and dump the viewstate code that persists the data table.
推荐阅读
- c# - Xamarin.iOS PeformSegue 不使用异步/等待
- excel - AutoFilter Criteria Range 不采用数组
- node.js - Node C++ 模块共享库
- android - Firebase Storage图片通过Android App上传成功,但如何获取url?
- reactjs - 在 Material-ui 包装器组件中定位和设置特定子元素的正确方法?
- react-native - 如何渲染方形 ListItem 头像而不是圆形?
- c++ - 为什么这个模板定义了一组与 void 匹配的别名类型?
- bash - 在具有特定扩展名的所有文件夹和子文件夹中运行命令
- java - 如何在customtextview中将可变文本值与固定字符串连接起来
- java - 如何根据倒数计时器模糊图像