Latest Entries »

Saturday, April 9, 2011

SelectedIndexChanged doesn't fire with autopostback true in ASP.NET in List Control

Rarely when developing application in ASP.NET you stuck on any ListControl and AutoPostBack="true" and SelectedIndexChanged won't trigger. Even when server receive postback your control don't response at all.

Today I will show and explain the problem: duplicate values inside ListItem.

RatioButtonList example

Now let imagine we have that piece of code:



        protected void rblShippingMethods_IndexChanged(object sender, EventArgs e)
        {
            //This action is always performed when user change item in RadioButtonList Control
            do_rblShippingMethods_IndexChanged();
        }

Let imagine that our datasource produce something like that. In this scenario we have shipping method as text and shipping method price as value for RadioButtonList :

        
        
        


Nothing complicated and this will work almost everytime.

houston we have a problem!


But when we have ListControl with Binding from any datasource it may happen that one or more ListItem can have the same value.When that situation happen rblShippingMethods_IndexChanged won't trigger.



        
        
        
        
        



I'm really confused when I wrote a solution for this case because event is connected with Index not Value inside ListControl. But nothing is perfect.

Don't panic!

What to do when two or more ListItem have the same value? Maybe ask end user to put diffrent values in user form! Oh no really it's dummy thought! We make our users happy and everything will work as always.

First thing we need to observe is fact the PostBack is send to server. Breakpoint was hit. But not the SelectedIndexChanged.

Think, think, think... BINGO

So when we found that server receive request we have to find which control causes the postback to our server. We can do it with
//Return full ClientID of postback source. So we can find the name of control and index
//For example:
//control = ctl00$MainContent$wizSubmitOrder$rblShippingMethods$0
//control = ctl00$MainContent$wizSubmitOrder$rblShippingMethods$1
//control = ctl00$MainContent$wizSubmitOrder$rblShippingMethods$2
String control = Request["__EVENTTARGET"];
We can see that only last part after $ sign is changing. That is our SelectedIndex!
So we can put this piece of code inside Page_Load:
if (Page.IsPostBack)
{
    rblShippingMethods_CustomMethodIndexChanged();
}
protected void rblShippingMethods_CustomMethodIndexChanged()
{
    String control = Request["__EVENTTARGET"];
    String args = Request["__EVENTARGUMENT"];
    if (control != null)
    {
        if (control.Contains("rblShippingMethods"))
        {
            String selectedIndex = control.Substring(control.LastIndexOf("$") + 1);
            int si = 0;
            if (int.TryParse(selectedIndex, out si))
            {
                //We manually chage selectedIndex and then we call
                //the same method when normally rblShippingMethods_IndexChanged event
                //would occur
                rblShippingMethods.SelectedIndex = si;
                do_rblShippingMethods_IndexChanged();
            }
        }
    }
}

0 comments:

Post a Comment