DropDownList OnSelectedIndexChange到第0个索引w / out ViewState [英] DropDownList OnSelectedIndexChange to 0th index w/out ViewState

查看:155
本文介绍了DropDownList OnSelectedIndexChange到第0个索引w / out ViewState的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我确实遵循文章 TRULLY了解ViewState (伟大的文章btw)和填充我的下拉列表是非常好的。我甚至设置了一个OnSelectedIndexChange事件,这个事件几乎一样好。



我发现的问题是SelectedIndexChanged事件在选择第0个索引时不会触发。不过,这样做还是其他时间。



这里有一些代码:

  < asp:DropDownList runat =serverID =DropDownList1EnableViewState =false
AutoPostBack =TrueOnSelectedIndexChanged =DropDownList1_SelectedIndexChanged/>


  protected override void OnInit(EventArgs e)
{
this.DropDownList1.DataTextField =Text;
this.DropDownList1.DataValueField =Value;
this.DropDownList1.DataSource = fillQueueDropDown();
this.DropDownList1.DataBind();

base.OnInit(e);
}

protected void DropDownList1_SelectedIndexChanged(object sender,EventArgs e)
{
OnSelectedQueueChanged(e);
}

public void OnSelectedQueueChanged(EventArgs e)
{
//做东西
}

public event EventHandler queueNamesChangedEvent;
public void OnSelectedQueueChanged(EventArgs e)
{
if(queueNamesChangedEvent!= null)
queueNamesChangedEvent(this,e);
}

我想我可以在Page_Load方法中进行一些类型的检查: p>

  if(ViewState [selectedIndexChangedFlag]!= 1)
// raise OnSelectedChange事件



请参阅,我的自定义EventHander引发了一个由该控件所在的父页面捕获的事件,以便父级可以使用新选择的值进行一些操作。这个目前正在为所选索引> 0的所有情况工作。



我在此控件中创建一个包含最近选择的索引的属性,在这种情况下,我的父页面可以对每个Page_Load ... dunno上的此属性值进行操作。



打开到建议。或者如何强制这个SelectedIndexChanged事件触发第0个索引选择。

解决方案

我的目标是禁用ViewState在这个下拉列表列表是最小化页面的ViewState的大小。



我只用if(!Page.IsPostBack){... DataBind() ...},是当您第一次选择一个项目,并且页面重新加载时,我的下拉列表将变为空。



我最后做的是在此控件LastIndex上创建另一个属性。 OnSelectedIndexChanged事件触发时,我更新LastIndex值。在Page_Load中,我比较了当前值和最后索引值,如果它们不同,则触发索引更改事件。

  public int SelectedValue {
get {return this.DropDownList1.SelectedItem.Value; }
}

public int LastIndex {
get {return this.ViewState [lastIndex] == null? -1:(int)this.ViewState [lastIndex]; }
set {this.ViewState [lastIndex] = value; }
}

protected override void OnInit(EventArgs e){
base.OnInit(e);
this.DropDownList1.DataTextField =Text;
this.DropDownList1.DataValueField =Value;
this.DropDownList1.DataSource = fillQueueDropDown();
this.DropDownList1.DataBind();
}

protected void Page_Load(object sender,EventArgs e){
if(this.LastIndex!= this.SelectedValue)
this.OnSelectedQueueChanged(new EventArgs ));
}

private ListItemCollection fillQueueDropDown(){...}

protected void DropDownList1_SelectedIndexChanged(object sender,EventArgs e){
OnSelectedQueueChanged(e) ;
this.LastIndex = this.SelectedValue;
}

public event EventHandler queueNamesChangedEvent;
public void OnSelectedQueueChanged(EventArgs e){
if(queueNamesChangedEvent!= null)
queueNamesChangedEvent(this,e);
}

你是对的在OnInit阶段重新加载和重新绑定数据。然后ViewState被还原(当第0个索引被恢复时),当我们终于到达事件阶段时,控件不会检测到这个变化。



不确定这是最优雅的路线,但到目前为止,它的运行良好。



然后我在msdn文档中找到了IPostBackDataHandler:

  public virtual bool LoadPostData(string postDataKey,
NameValueCollection postCollection){

String presentValue = Text;
String postedValue = postCollection [postDataKey];

if(presentValue == null ||!presentValue.Equals(postedValue)){
Text = postedValue;
返回true;
}

return false;
}

由于当前值与更改值相同,因此事件没有被解雇。


I did follow the article TRULLY Understanding ViewState (great article btw) and populating my drop down list is working great. I've even setup a OnSelectedIndexChange event which fires almost as great.

The problem I've found is the SelectedIndexChanged event won't fire when selecting the 0th index. It does all other times however.

Here's some code:

<asp:DropDownList runat="server" ID="DropDownList1" EnableViewState="false" 
AutoPostBack="True" OnSelectedIndexChanged="DropDownList1_SelectedIndexChanged" />


protected override void OnInit(EventArgs e)
{
    this.DropDownList1.DataTextField = "Text";
    this.DropDownList1.DataValueField = "Value";
    this.DropDownList1.DataSource = fillQueueDropDown();
    this.DropDownList1.DataBind();

    base.OnInit(e);
}

protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
{
    OnSelectedQueueChanged(e);
}

public void OnSelectedQueueChanged(EventArgs e)
    {
        // Do stuff.
    }

public event EventHandler queueNamesChangedEvent;
public void OnSelectedQueueChanged(EventArgs e)
    {
        if (queueNamesChangedEvent != null)
            queueNamesChangedEvent(this, e);
    }

I suppose I can do some type of check in the Page_Load method:

  if(ViewState["selectedIndexChangedFlag"] != 1)
      // raise OnSelectedChange event

Or is there something I can setup in the OnInit() method where I'm rebinding this data everytime that i can do?

See, my custom EventHander raises an event which is caught by a the parent page in which this control resides, so that the parent could take some action using the newly selected value. And this is currently working for all cases where the selected index > 0.

I create a property in this control which contains the most recently selected index, in which case my parent page can action on this property value on every Page_Load... dunno.

Open to suggestions. Or how to force this SelectedIndexChanged event to fire for that 0th index selection.

解决方案

My goal with disabling the ViewState on this drop down list is to minimize the size of the ViewState for the page.

The problem I had with only doing the if(!Page.IsPostBack){...DataBind()...}, is that when you select an item for the first time, and the page reloads, my drop down list becomes empty.

What I ended up doing was creating another Property on this control, LastIndex. When the OnSelectedIndexChanged event fires, I update the LastIndex value. In the Page_Load, I compare the Current and Last index values, if they're different, then fire a Index changed event.

    public int SelectedValue{
        get { return this.DropDownList1.SelectedItem.Value; }
    }

    public int LastIndex{
        get { return this.ViewState["lastIndex"] == null ? -1 : (int)this.ViewState["lastIndex"]; }
        set { this.ViewState["lastIndex"] = value; }
    }

    protected override void OnInit(EventArgs e){
        base.OnInit(e);
        this.DropDownList1.DataTextField = "Text";
        this.DropDownList1.DataValueField = "Value";
        this.DropDownList1.DataSource = fillQueueDropDown();
        this.DropDownList1.DataBind();
    }

    protected void Page_Load(object sender, EventArgs e){
        if (this.LastIndex != this.SelectedValue)
            this.OnSelectedQueueChanged(new EventArgs());
    }

    private ListItemCollection fillQueueDropDown(){...}

    protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e){
        OnSelectedQueueChanged(e);
        this.LastIndex = this.SelectedValue;
    }

    public event EventHandler queueNamesChangedEvent;
    public void OnSelectedQueueChanged(EventArgs e){
        if (queueNamesChangedEvent != null)
            queueNamesChangedEvent(this, e);
    }

You are right though. The data is re-loaded and re-bound in the OnInit phase. Then the ViewState is restored (and when the 0th index is restored), when we finally get to the Events phase, the control doesn't detect the change.

Not sure this is the most elegant route, but it's working good so far.

Then i found this in the msdn docs for IPostBackDataHandler:

  public virtual bool LoadPostData(string postDataKey, 
     NameValueCollection postCollection) {

     String presentValue = Text;
     String postedValue = postCollection[postDataKey];

     if (presentValue == null || !presentValue.Equals(postedValue)) {
        Text = postedValue;
        return true;
     }

     return false;
  }

Since the present value is the same as the changed-to value, the event isn't fired.

这篇关于DropDownList OnSelectedIndexChange到第0个索引w / out ViewState的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆