Reputation: 2148
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. Two of the columns are drop downs as I want the user to be able to select a different (category and status). 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:
<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:
<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?
Upvotes: 0
Views: 935
Reputation: 48989
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.
Upvotes: 1