RE: ASP.NET 2.0 Dropdownlist EnableViewState=false SelectedIndexCh

Tech-Archive recommends: Repair Windows Errors & Optimize Windows Performance



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>

.



Relevant Pages

  • Re: DropDownList
    ... > I'm having trouble with multiple dynamically generated dropdownlists. ... > I have no problem setting the other controls to display what I would like ... > selectedindex to be different for each of the controls. ...
    (microsoft.public.dotnet.framework.aspnet)
  • Re: Need some help on forms
    ... You know with buttons, labels, picture boxes, lists & stuff like that. ... WizardController class to act as the user process component that controls ... In the Form designer select a ListBox that you want to bind to a data ...
    (microsoft.public.dotnet.framework.adonet)
  • Re: Selecting more than one item from a list.
    ... You mean a Delphi program? ... endless list of controls and non-visual controls in the palette; ... read once, but it's really about the lists of properties, methods, and ... up are writing your own classes when you need them (and equally important, ...
    (comp.lang.pascal.delphi.misc)
  • Re: Would Like VBA that Lists All QAT Controls, Displays their ICon and Description
    ... I think you might have to do it manually, but using a screen capture program such as Snagit from www.techsmith.com would allow you to build up a graphical image of the commands and their icons to which you could add the tooltips. ... Doug Robbins - Word MVP, ... >> Me and a partner are trying to make an index of the QAT controls so ... >> a table of 3 columns that lists out all the Control names, ...
    (microsoft.public.word.vba.beginners)
  • Re: How to bind to a drop down list in a grid.
    ... > I want to display some drop down lists in a grid. ... > the right place to bind the lists, ... > cant find an event during the load up that gives me access to the controls ...
    (microsoft.public.dotnet.framework.aspnet.datagridcontrol)