在asp.net中连线事件被调用但是设置的页面属性未得到反映

问题描述

| 我有一个7个网页和一个声明一些属性,事件和一些功能的类。此类的对象(即_ItemSetup)被移入所有页面,并且在所有页面上维护相同的副本。基于ItemSetup类的此对象,可以执行某些业务决策并更改值。
public class ItemSetup 
{

    /// <summary>
    /// Raises an event after FK_ITEM_TYPE property has changed.  
    /// PropertyChanged object returns value of FK_ITEM_TYPE before change and after change
    /// </summary>
    public event EventHandler<PropertyChanged> ItemTypeChanged;


    private long fK_ITEM_TYPE;
    /// <summary>
    /// Item type can be-Package,Subassembly,cash and many more.
    /// So each item type will have different behavIoUr based on which validation changes.
    /// \"ItemTypeChanged\" event is triggered when this property value is changed.
    /// </summary>
    public long FK_ITEM_TYPE 
    {
        get { return fK_ITEM_TYPE; }
        set 
        {
            if (value == fK_ITEM_TYPE)
                return;
            fK_ITEM_TYPE = value;

            PropertyChanged eOnChanged = new PropertyChanged(null,value);
            if (ItemTypeChanged!= null)
                ItemTypeChanged(this,eOnChanged);
        }
    }
 }
文件后面的代码用于引发事件。
public partial class Itemmaster_Main : System.Web.UI.Page
{

    public ItemSetup _ItemSetup { get; set; }

    protected void Page_Load(object sender,EventArgs e)
    {
        ItemSetup.MenuBarEventAssociation(Itemmenu,SaveInputValues);

        if (!IsPostBack)
        {
            BindDropDown();

            if (Session[\"ItemSetup\"] != null)
            {
                _ItemSetup = Session[\"ItemSetup\"] as ItemSetup;
                //Do something.
            }
            else
            {
                _ItemSetup = new ItemSetup(ItemSetup.OperationMode.Add);
                _ItemSetup.ItemTypeChanged += new EventHandler<PropertyChanged>(_ItemSetup_ItemTypeChanged);

                Session[\"ItemSetup\"] = _ItemSetup;
            }
        }
        _ItemSetup = Session[\"ItemSetup\"] as ItemSetup;
    }

    protected void cmbItemType_SelectedindexChanged(object sender,EventArgs e)
    {
        _ItemSetup.FK_ITEM_TYPE = long.TryParse(cmbItemType.SelectedValue,out outLong) ? outLong : (long)L_ITEM_TYPE.SelectOne;

        // When I calls this as a functions. It do its work and sets the css.
        //_ItemSetup_ItemTypeChanged(null,null);
    }

    void _ItemSetup_ItemTypeChanged(object sender,PropertyChanged e)
    {
        //Hide or show button based on conditions
        btnNext.Visible = !(_ItemSetup.FK_ITEM_TYPE == (int)AARFID.DataLayer.L_ITEM_TYPE.SelectOne);

        //Hide all controls until Item Type is not selected.           
        if (_ItemSetup.FK_ITEM_TYPE == (long)L_ITEM_TYPE.SelectOne)
            divControlBox.Attributes.Add(\"style\",\"display:none;\");
        else
            divControlBox.Attributes.Add(\"style\",\"display:block;\");
    }
}
在任何时候设置属性FK_ITEM_TYPE都会引发_ItemSetup_ItemTypeChanged事件,并且将执行写入该函数的所有代码。我希望控件应该被隐藏。但这对页面没有任何作用。 我没有得到该事件不影响页面的原因。 当我取消注释函数cmbItemType_SelectedindexChanged中的行时 即   // _ ItemSetup_ItemTypeChanged(null,   空值); 属性和CSS被设置,页面行为符合预期。 可能是什么原因。 编辑 如果我将事件处理程序关联到我们的IsPostBack旁边,则页面会根据需要生效,但事件不断增加
(_ItemSetup.ItemTypeChanged as EventHandler<PropertyChanged>).GetInvocationList()
{System.Delegate[17]}
    [0]: {Method = {Void ItemSetup_ItemTypeChanged(System.Object,AARFID.DataLayer.PropertyChanged)}}
    [1]: {Method = {Void _ItemSetup_ItemTypeChanged(System.Object,AARFID.DataLayer.PropertyChanged)}}
    [2]: {Method = {Void _ItemSetup_ItemTypeChanged(System.Object,AARFID.DataLayer.PropertyChanged)}}
    [3]: {Method = {Void _ItemSetup_ItemTypeChanged(System.Object,AARFID.DataLayer.PropertyChanged)}}
    [4]: {Method = {Void _ItemSetup_ItemTypeChanged(System.Object,AARFID.DataLayer.PropertyChanged)}}
    [5]: {Method = {Void _ItemSetup_ItemTypeChanged(System.Object,AARFID.DataLayer.PropertyChanged)}}
    [6]: {Method = {Void _ItemSetup_ItemTypeChanged(System.Object,AARFID.DataLayer.PropertyChanged)}}
    [7]: {Method = {Void _ItemSetup_ItemTypeChanged(System.Object,AARFID.DataLayer.PropertyChanged)}}
    [8]: {Method = {Void _ItemSetup_ItemTypeChanged(System.Object,AARFID.DataLayer.PropertyChanged)}}
    [9]: {Method = {Void _ItemSetup_ItemTypeChanged(System.Object,AARFID.DataLayer.PropertyChanged)}}
    [10]: {Method = {Void _ItemSetup_ItemTypeChanged(System.Object,AARFID.DataLayer.PropertyChanged)}}
    [11]: {Method = {Void _ItemSetup_ItemTypeChanged(System.Object,AARFID.DataLayer.PropertyChanged)}}
    [12]: {Method = {Void _ItemSetup_ItemTypeChanged(System.Object,AARFID.DataLayer.PropertyChanged)}}
    [13]: {Method = {Void _ItemSetup_ItemTypeChanged(System.Object,AARFID.DataLayer.PropertyChanged)}}
    [14]: {Method = {Void _ItemSetup_ItemTypeChanged(System.Object,AARFID.DataLayer.PropertyChanged)}}
    [15]: {Method = {Void _ItemSetup_ItemTypeChanged(System.Object,AARFID.DataLayer.PropertyChanged)}}
    [16]: {Method = {Void _ItemSetup_ItemTypeChanged(System.Object,AARFID.DataLayer.PropertyChanged)}}
    

解决方法

每次回发时,_ItemSetup实例都会失去其事件处理程序的正确接线,因此您必须在每次页面加载时添加它们,并在页面卸载时将其删除。简而言之:
protected void Page_PreInit(object sender,EventArgs e)
    {
        if (Session[\"ItemSetup\"] == null)
        {
            _ItemSetup = new ItemSetup();
            Session[\"ItemSetup\"] = _ItemSetup;
        }

        _ItemSetup = Session[\"ItemSetup\"] as ItemSetup;
        _ItemSetup.ItemTypeChanged += _ItemSetup_ItemTypeChanged;            
    }

protected void Page_Unload(object sender,EventArgs e)
    {
        _ItemSetup.ItemTypeChanged -= _ItemSetup_ItemTypeChanged;
    }
    ,页面加载方法在处理事件之前被触发。 ASP页面生命周期的理解相当复杂,但是您应该让事件处理程序来完成工作,而不是页面加载方法。