Why DropDownList.SelectedIndexChanged event does n

2019-04-01 01:42发布

问题:

I have a DropDown which is bounded to an ObjectDataSource. On its data bound event, I am adding "--select--" value on the 0 index. I have a LinkButton on the page and on its client click, i am selecting different item on drop down (using JavaScript). Suppose there are 3 items like --select--, option1, option2 and option3 and now on link button's client click i selected option3, now if I select the default value "--select--", it does not fire the SelectedIndexChanged event. If I select any other value then it fires. Why does it not work for the default value?

protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack && !IsCallback)
    {
      this.FillDropDown("--Select--");
    }
    else
    {                            
        if (this.drp.SelectedItem != null)
            this.FillDropDown(this.drp.SelectedItem.Text);
        else
            this.FillDropDown("--Select--");
    }
}

protected void FillDropDown(string viewName)
{       
    this.obJectDataSource.Select();

    this.drp.Items.Clear();
    this.drp.SelectedIndex = -1;
    this.drp.DataBind();

    if (this.drp.Items.Count > 0)
    {           
        ListItem item = this.drp.Items.FindByText(viewName);
        if (item == null)
        {
            item = this.drp.Items.FindByText("--Select--");
        }
        if (item != null)
        {
            int selectedIndex = this.drp.Items.IndexOf(item);
            this.drp.Items[selectedIndex].Selected = true;
            this.drp.SelectedIndex = selectedIndex;                        
        }
    }
}

protected void drp_OnDataBound(object sender, EventArgs e)
{
    if (this.drp.Items.Count > 0)
    {               
        this.drp.Items.Insert(0, new ListItem("--Select--", "-1"));                
    }                        
}

protected void drp_SelectedIndexChanged(object sender, EventArgs e)
{            
    if (drp.SelectedValue != "-1")
    {
        Session["SelectedItem"] = this.drp.SelectedItem.Text;

    }            
}
/// The button which do callback not postback

<dx:ASPxCallback ID="ASPxCallback1" runat="server" ClientInstanceName="Callback1" OnCallback="SaveFilter_Click">
    <ClientSideEvents CallbackComplete="function(s,e){Callback1Success(s,e);}" />
</dx:ASPxCallback>

<dx:ASPxButton ID="btn_Save" runat="server" CausesValidation="False" Height="20px" Text="Save" AutoPostBack="false" UseSubmitBehavior="false">
    <ClientSideEvents Click="function(s, e) {
            var isValid =  Validate(this, txt1.GetText());
            if(isValid==true) {
                Callback1.PerformCallback('Save');                               
            }  
            else {
                e.processOnServer = false;
            }}">
    </ClientSideEvents>
</dx:ASPxButton>

protected void SaveFilter_Click(object sender, CallbackEventArgs e)
{
    if (e.Parameter.ToString() == "Save")
    {
        if (!string.IsNullOrEmpty(txt_SaveSaveSearch.Text))
        {
            // saving data into data base.
            this.FillDropDown(txt.Text);                    
            e.Result = ASPxCallback.GetRenderResult(this.drp);
        }
    }
}

function Callback1Success(s,e) {
     var ctrl = document.getElementById('ctl00_ContentHolder_drp');
     ctrl.outerHTML = e.result;        
}

回答1:

Update:

Based on the revised question -

  1. Why don't you set AppendDataBoundItems on the dropdownlist? The property would allow the dropdownlist to append items to the existing ones.

    <asp:DropDownList ID='DropDownList1' runat='server' AutoPostBack='true'  EnableViewState='true' AppendDataBoundItems='true'>
    
        <asp:ListItem Selected='True' Text='--Select--' Value='1'></asp:ListItem></asp:DropDownList>
    
  2. The Page_Load method doesn't do what you want to. The else part of it will be executed even if one of them is true ..ex: if "Postback is true" or "callback is true" it would go into the else part. But as suggested in the (1) step, set the AppendDataBoundItems and remove code to add "--select--".


Most likely issue be with ViewState, Set EnableViewState="true"

<%@ Page Title="" Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true" CodeFile="Test.aspx.cs" EnableViewState="true"%>

And if you are using Maste Pages you'll have to enable on it too.

<%@ Master Language="C#" AutoEventWireup="true" CodeFile="Site.master.cs" Inherits="Site" EnableViewState="true" ClassName="Site" %>

And in the dropdown web control AutoPostback="true"

<asp:DropDownList ID='DropDownList1' runat='server' AutoPostBack='true' 
    OnSelectedIndexChanged='HandleOnDropDownListSelectedIndexChanged'>
</asp:DropDownList>


回答2:

I don't know if anyone else had the same Issue as I did but it just so happened that my values were the same for each item in the drop down list and it would never fire the event until I changed the values.



回答3:

Another cause of this is if you have more than one form on the page... I had placed a second form on the page that didn't have an ID or action yet. This form was interfering with the form that contained the control for which I was trying to fire the onselectedindexchanged handler...

I guess if all else fails, make sure you only have a SINGLE form in your markup.



回答4:

I experienced the same issue, after a while digging in I found that the designer code is not in sync with the changes that I made in .aspx, the code behind which is still has some references to control that was deleted is causing object reference not set to instance of object error, but that's happening at some special case handling which is nothing to do with the actual issue (onselectionchanged not firing)..

... but I also noticed that there is some jscript in .aspx which is still contain the old references of control I deleted. The compiler didnt prompt any error as this is javascript which are caught only at runtime. Hence I concluded in my case that the javascript issue is preventing autopostback event.