订阅尚未创建的对象的事件?

时间:2014-03-25 01:51:46

标签: c# sql-server events

嗯,我真的怀疑这是否可能,但也许毕竟它可能。 我希望在我的程序初始化时订阅一个事件,但是在我的表单加载后很久就会创建该对象。在订阅时,该对象为null,但稍后创建。是否可以更新该对象以便触发事件?

在Form_Load中,我订阅了这个

  this.mediaCenter.ItemManager.Root.SetProgressBar += (val) => 
        { 
             this.Invoke((Action)(() =>
            {
                this.progressBarControl1.Position = val;
            }));
        };

在项目管理器中,表单加载期间对象为空

   private ItemContainerRoot _myRoot;
        public ItemContainerRoot Root
        {
            get { return this._myRoot; }
        }

稍后我的数据库将获取对象

this._myRoot = context.GetTable<Item>().Single(a => a.Id == 0) as ItemContainerRoot;

2 个答案:

答案 0 :(得分:1)

试试这个:

在类库中,在Root属性更改时通知并在任何地方使用属性(而不是字段)。

class ItemManager : INotifyPropertyChanged
{
    private ItemContainerRoot _myRoot;
    public ItemContainerRoot Root
    {
        get { return _myRoot; }

        set
        {
            _myRoot = value;
            OnPropertyChanged("Root");
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}    

在UI中订阅初始化后ItemManager的属性更改事件:

ItemManager.PropertyChanged += (o, args) =>
{
     if (args.PropertyName == "Root" && ItemManager.Root != null)
     {
          ItemManager.Root.SetProgressBar += (val) =>
          {
               this.Invoke((Action)(() =>
               {
                    this.progressBarControl1.Position = val;
               }));
          };
     }
};

答案 1 :(得分:0)

如果你真的想要做到这一点,你需要跳过几个环节:

private Action _myRootDisconnect = null;
private object _myRootGate = new object();
private ItemContainerRoot _myRoot;
public ItemContainerRoot Root
{
    get { return _myRoot; }
    set
    {
        lock (_myRootGate)
        {
            Action<int> setProgressBar = val =>
            {
                this.Invoke((Action)(() =>
                {
                    this.progressBarControl1.Position = val;
                }));
            };

            if (_myRootDisconnect != null)
            {
                _myRootDisconnect();
                _myRootDisconnect = null;
            }

            _myRoot = value;
            _myRoot.SetProgressBar += setProgressBar;

            _myRootDisconnect = () =>
            {
                _myRoot.SetProgressBar -= setProgressBar;
            };
        }
    }
}

基本上,只要您将实例分配给属性(而不是字段),此代码就会将您的事件连接起来。

它有一个lock,因为您显然是从另一个线程调用此代码(但我不知道为什么)。

它还会创建一个名为Action的{​​{1}},以便您在重新分配_myRootDisconnect时(或在您完全退出代码时)断开事件。