GridView OnRowDataBound & Page.EnableViewState
Hello, Am facing this peculiar problem with a dropdownlist in the Gridview. Due to performance reasons, I've turned off the Page's ViewState. As a result I pay the price of fetching the values each time from the DB upon postback. In the gridview, I got a dropdown list for each line that pre-selects an option depending on the DB value for that column. I have the OnRowDataBound event firing up everytime a DataBind happens. In that, I find the dropdownlist control and set it's SelectedIndex property depending upon the value from the DB, but for some strange reason the set value is lost upon render. Here's the test project's code::
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.c s" EnableViewState="False" Inherits="_Default" %>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<asp:TextBox ID="txtId" runat="server"></asp:TextBox>
<br />
<asp:GridView ID="grd" runat="server" AutoGenerateColumns="false" OnRowDataBound="HandleRowBound">
<Columns>
<asp:BoundField HeaderText="Name" DataField="Name" />
<asp:TemplateField HeaderText="Action">
<ItemTemplate>
<asp:DropDownList ID="ddlAction" runat="server">
<asp:ListItem Text="" Value="0"></asp:ListItem>
<asp:ListItem Text="Ok" Value="1"></asp:ListItem>
</asp:DropDownList>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</form>
</body>
</html>
Codebehind
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Collections.Generic;
public partial class _Default : Page
{
protected void Page_Load(object sender, EventArgs e)
{
this.grd.DataSource = this.LoadData();
this.grd.DataBind();
}
private List<GridClass> LoadData()
{
List<GridClass> coln = new List<GridClass>();
GridClass obj = new GridClass();
obj.Name = "First";
obj.Action = 0;
coln.Add(obj);
obj = new GridClass();
obj.Name = "Second";
obj.Action = 1;
coln.Add(obj);
if (this.txtId.Text.Length > 0)
return coln.FindAll(delegate(GridClass find) { return find.Name == this.txtId.Text; });
else
return coln;
}
protected void HandleRowBound(object sender, GridViewRowEventArgs e)
{
GridViewRow row = e.Row;
GridClass obj = row.DataItem as GridClass;
if (row.RowType == DataControlRowType.DataRow)
{
DropDownList ddl = row.Cells[1].FindControl("ddlAction") as DropDownList;
ddl.SelectedIndex = ddl.Items.IndexOf(ddl.Items.FindByValue(obj.Action .ToString()));
}
}
}
public class GridClass
{
private string name;
public string Name
{
get { return name; }
set { name = value; }
}
private int action;
public int Action
{
get { return action; }
set { action = value; }
}
}
To reproduce the issue:
1) Browse the page, Grid renders 2 rows. First row's dropdownlist selects the first item while the second row's dropdownlist selects the second item.
2) In the textbox, type the name "Second" and hit enter. The grid view renders only one row, but notice that the dropdownlist does not show the correct selection. But you can see in the HandleRowBound event that am setting the appropriate index. But upon rendering the selection is lost! Any idea why this would happen? Is there any link between turning the ViewState off & the controls in GridView?
Appreciate your help.
|