嗯,我真的怀疑这是否可能,但也许毕竟它可能。 我希望在我的程序初始化时订阅一个事件,但是在我的表单加载后很久就会创建该对象。在订阅时,该对象为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;
答案 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
时(或在您完全退出代码时)断开事件。