RE: ASP.NET 2.0 Dropdownlist EnableViewState=false SelectedIndexCh
- From: "Anson Goldade" <AnsonGoldade@xxxxxxxxxxxxxxxxxxxxxxxxx>
- Date: Thu, 9 Feb 2006 10:50:26 -0800
Phillip,
I absolutely agree with our assessment. However, with the new ControlState
model that was implemented in controls in ASP.NET 2.0, we shouldn't need view
state to have the control update it's selectedindex between when the control
is populated in PreInit and when the event is subscribed to in OnLoad.
According to the MSDN docs, all viewstate (and I'm assuming that includes
controlstate) is restored by the time that OnLoad is called. This should
mean that the selected index has been reset to the value it was prior to the
postback.
To illustrate this, disable ViewState and check what the selected index just
prior to me subscribing to the selectedindexchanged events in OnLoad. Since
I don't subscribe to the events until the index has been reset (and prior to
the postback data being processed) only the controls that actually had value
changes should fire the selectedindexchanged events.
Perhaps I'm missing something with the new ControlState model. I started
going down this path based on the following article.
http://msdn.microsoft.com/msdnmag/issues/04/10/ViewState/default.aspx
The overall goal here is to not have to enable viewstate, but continue to
have the controls firing the server side events. I don't mind repopulating
the list controls ... in fact I find that much preferrable to serializing 10K
of viewstate to a client that just ends up posting that back to me.
I'm just trying to figure out if I'm doing something wrong or if I'm missing
the point completely. Thanks again for your time and feedback and I look
forward to working with you toward a resolution.
Anson Goldade
"Phillip Williams" wrote:
Hi Anson,.
I put your code on my site to illustrate to you what is happening:
http://www.webswapp.com/codesamples/testMultipleEventsOnPostBack.aspx
The problem here is that when you set the EnableViewState to false, you have
reconstructed the dropdownlists on every postback. After reconstructing
them, (at the end of the OnPreInit), the selectedindex is always =0.
Therefore if you had changed the first dropdownlist (which fired the first
event) then changed the second dropdownlist, the event of the first would
still be fired because as far as the page is concerned you have changed both
dropdownlist from the time you reconstructed them.
Your problem disappeared when you set the EnableViewState to true because
after the OnPreInit the state of the first dropdownlist (from previous
postback) changed the selectedIndex of your list and therefore the
dropdownlist did not sense a change in the selectedindex.
--
HTH,
Phillip Williams
http://www.societopia.net
http://www.webswapp.com
"Anson Goldade" wrote:
I'm trying to leverage the viewstate optimization capabilities in ASP.NET 2.0
but have run into an issue with the DropDownList.
Problem statement
SelectedIndexChanged events are getting fired for every dropdown since the
page was first rendered. Here's a sequence example.
1. Load page
2. Change value in ddl #1 ... causes postback. SelectedIndexChanged fired
for ddl #1.
3. Change value in ddl #2 ... causes postback. SelectedIndexChanged fired
for ddl #1 and ddl #2. This is the unexpected behavior. Would only expect
SelectedIndexChanged to be fired for ddl #2
Assumptions
1. Multiple drop down lists on page
2. Autopostback = true
3. EnableViewState on page = false
4. Each ddl has it's own selectedindexchanged event
5. Lists in the ddl's are being rebuilt by overriding OnPreInit on page.
Also tried populating lists in OnInit and OnInitComplete ... same result
6. Subscribe to SelectedIndexChanged event in OnLoad. Also tried setting
onselectedindexchanged properties of ddl in aspx ... same result.
I'd like to know what I need to do in order to get only the
SelectedIndexChanged event to fire for the control that actually changed. If
I set EnableViewState=true, the expected behavior is exhibited. I've
attached a sample scenario below. Your help is appreciated. Thanks.
Anson
<aspx_page>
<%@ Page Language="C#" AutoEventWireup="false"
CodeFile="TestMultipleEventsOnPostback.aspx.cs"
Inherits="TestMultipleEventsOnPostback" enableviewstate="false" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>DropDownList SelectedIndexChanged EnableViewState="False"
Example</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:label id="summary" runat="server"></asp:label>
<br />
<br />
<table width="100%">
<tr>
<td>List #1</td>
<td>List #2</td>
<td>Repeater</td>
</tr>
<tr>
<td><asp:dropdownlist id="list1" runat="server"
autopostback="true"></asp:dropdownlist></td>
<td><asp:dropdownlist id="list2" runat="server"
autopostback="true"></asp:dropdownlist></td>
<td>
<table>
<asp:repeater id="repeat" runat="server">
<itemtemplate>
<tr>
<td><asp:label id="itemTemplateLabel"
runat="server"></asp:label></td>
<td><asp:dropdownlist id="itemTemplateList"
runat="server" autopostback="true"></asp:dropdownlist></td>
</tr>
</itemtemplate>
</asp:repeater>
</table>
</td>
</tr>
</table>
</div>
</form>
</body>
</html>
</aspx_page>
<aspx_cs_codebehind>
using System;
using System.Collections.Generic;
using System.Data;
using System.Configuration;
using System.Collections;
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;
public partial class TestMultipleEventsOnPostback : System.Web.UI.Page
{
//items for list #1
private Dictionary<string, string> _list1Items = new Dictionary<string,
string>();
//items for list #2
private Dictionary<string, string> _list2Items = new Dictionary<string,
string>();
//items for repeater drop down
private Dictionary<string, string> _repeaterListItems = new
Dictionary<string, string>();
//repeater source just to get 5 items created
private object[] _repeaterSource = new object[5];
public TestMultipleEventsOnPostback()
{
//create the list 1 items
for (int i = 0; i <= 10; i++)
{
this._list1Items.Add(i.ToString(), string.Format("Value = {0}",
i));
}
//create the list 2 items
for (int i = 0; i <= 40; i++)
{
this._list2Items.Add(i.ToString(), string.Format("Value = {0}",
i));
}
//create the list repeater items
for (int i = 0; i <= 60; i++)
{
this._repeaterListItems.Add(i.ToString(), string.Format("Value =
{0}", i));
}
}
protected override void OnPreInit(EventArgs e)
{
//populate the drop down lists and rebuild the repeater
this.list1.DataTextField = "Value";
this.list1.DataValueField = "Key";
this.list1.DataSource = this._list1Items;
this.list1.DataBind();
this.list2.DataTextField = "Value";
this.list2.DataValueField = "Key";
this.list2.DataSource = this._list2Items;
this.list2.DataBind();
//rebuild the repeater control
this.repeat.ItemDataBound += new
RepeaterItemEventHandler(repeat_ItemDataBound);
this.repeat.DataSource = this._repeaterSource;
this.repeat.DataBind();
base.OnPreInit(e);
}
protected override void OnLoad(EventArgs e)
{
if (!this.IsPostBack)
{
this.summary.Text = "No postback";
}
else
{
//clear out the summary label
this.summary.Text = "<b>Event's that fired for current postback
(Note: I would only expect 1 because all the dropdowns have
autopostback=\"true\")</b>";
}
//set up the event handlers
this.list1.SelectedIndexChanged += new
EventHandler(list1_SelectedIndexChanged);
this.list2.SelectedIndexChanged += new
EventHandler(list2_SelectedIndexChanged);
//set up the event for the drop down in the repeater
foreach (RepeaterItem item in this.repeat.Items)
{
DropDownList ddl =
(DropDownList)item.FindControl("itemTemplateList");
ddl.SelectedIndexChanged += new
EventHandler(itemTemplateList_SelectedIndexChanged);
}
base.OnLoad(e);
}
protected void itemTemplateList_SelectedIndexChanged(object sender,
EventArgs e)
{
this.summary.Text += "<br/>itemTemplateList_SelectedIndexChanged";
}
protected void list2_SelectedIndexChanged(object sender, EventArgs e)
{
this.summary.Text += "<br/>list2_SelectedIndexChanged";
}
protected void list1_SelectedIndexChanged(object sender, EventArgs e)
{
this.summary.Text += "<br/>list1_SelectedIndexChanged";
}
protected void repeat_ItemDataBound(object sender, RepeaterItemEventArgs
e)
{
DropDownList ddl =
(DropDownList)e.Item.FindControl("itemTemplateList");
ddl.DataTextField = "Value";
ddl.DataValueField = "Key";
ddl.DataSource = this._repeaterListItems;
ddl.DataBind();
}
}
</aspx_cs_codebehind>
- References:
- ASP.NET 2.0 Dropdownlist EnableViewState=false SelectedIndexChange
- From: Anson Goldade
- RE: ASP.NET 2.0 Dropdownlist EnableViewState=false SelectedIndexChange
- From: Phillip Williams
- ASP.NET 2.0 Dropdownlist EnableViewState=false SelectedIndexChange
- Prev by Date: RE: ASP.NET 2.0 Dropdownlist EnableViewState=false SelectedIndexChange
- Next by Date: RE: ASP.NET 2.0 Dropdownlist EnableViewState=false SelectedIndexCh
- Previous by thread: RE: ASP.NET 2.0 Dropdownlist EnableViewState=false SelectedIndexChange
- Next by thread: RE: ASP.NET 2.0 Dropdownlist EnableViewState=false SelectedIndexCh
- Index(es):
Relevant Pages
|