C# 从不同类向多个表单发送更新事件-WPF
结构 我有一个简单的表单,可以启动一个计时器,定期检查更新。加载时启动的窗体的构造函数如下所示:C# 从不同类向多个表单发送更新事件-WPF,c#,wpf,events,inotifypropertychanged,C#,Wpf,Events,Inotifypropertychanged,结构 我有一个简单的表单,可以启动一个计时器,定期检查更新。加载时启动的窗体的构造函数如下所示: public MainWindow() { InitializeComponent(); otherWindow = new TheOtherWindow(); if (Meta.hasUpdate) { updateImage.Source = new BitmapImage(new Uri("/My
public MainWindow()
{
InitializeComponent();
otherWindow = new TheOtherWindow();
if (Meta.hasUpdate)
{
updateImage.Source = new BitmapImage(new Uri("/MyProject;component/Images/updateTrue.gif", UriKind.Relative));
}
Thread updateMonitor = new Thread(() =>
{
UpdateManager updater = new UpdateManager();
updater.StartUpdateMonitor();
});
updateMonitor.IsBackground = true;
updateMonitor.Start();
}
元类包含一些非常基本的信息,存储各种字符串,这些字符串在多个位置被引用,但有时会被更新。其中包括:
class Meta
{
...
private static bool hasUpdate = false;
public static bool GetHasUpdate()
{
return hasUpdate;
}
public static void SetHasUpdate(bool value)
{
hasUpdate = value;
}
}
另一部分是UpdateManager类,它包括一个小例程,每5分钟检查一次更新
class UpdateManager
{
Timer timer;
public void CheckForUpdates(Object source, ElapsedEventArgs e)
{
if (!isUpToDate())
{
timer.Stop();
Meta.SetHasUpdate(true);
Application.Current.Dispatcher.Invoke(new Action(() =>
{
MessageBox.Show("A new update is now available!);
}));
}
}
public void StartUpdateMonitor()
{
float updateInterval = 300000;
timer = new Timer(updateInterval); // Milliseconds between checks.
timer.Elapsed += CheckForUpdates;
timer.AutoReset = true;
timer.Enabled = true;
}
}
问题
简而言之,我想在到达Meta.SetHasUpdate()时触发一个事件,然后将其广播到应用程序中的所有表单,目的是更改一个小图标以指示更新可用
我尝试这样做的结果是,我认识到实现INotifyPropertyChanged并不能很好地处理静态成员。这是我试图实现的
class Meta : INotifyPropertyChanged
{
...
private static bool hasUpdate = true;
public static bool GetHasUpdate()
{
return hasUpdate;
}
public static void SetHasUpdate(bool value)
{
hasUpdate = value;
NotifyPropertyChanged();
}
private static void NotifyPropertyChanged()
{
if (PropertyChanged != null)
{
PropertyChanged(null, new PropertyChangedEventArgs("hasUpdate"));
}
}
}
由于这些成员需要从多个表单中读回,我不能在不大量传递对象的情况下使它们不是静态的,这是我不想做的
在这种情况下,如何触发多个窗体可以从元类接收的事件?我需要考虑一个不同的结构,或者我误解了IntIfyPrimTyType?< P>。虽然可以有很多方法来解决这个问题,(想想你的元类的DI到每个页面的VIEW模型中,并对IPC做出反应……这将比单点方法更好),一个要考虑的方法是使用消息而不是事件。消息(在大多数MVVM框架中提供)是松散耦合组件之间通信的好方法。如果您利用MVVM库,比如,那么这非常容易,因为它包含了一个Messenger实现。这种方法的主要优点是,您希望接收通知的表单不一定需要保留源的引用,就像使用基于事件的方法一样 只需让所有感兴趣的表单注册一条消息,并在收到消息时做出相应的反应 例如,使用MVVM Light,我们可以利用INPC属性更新后自动广播消息的优势
private bool hasUpdate;
public bool HasUpdate
{
{
return hasUpdate;
}
set
{
// the last bool param indicates whether or not to broadcast a message to all interested parties.
Set(nameof(HasUpdate), ref hasUpdate, value, true);
}
}
然后在应用程序的一个完全独立/不相关的部分(通常在ViewModel中),我们可以这样做以表明我们对此类更新感兴趣:
Messenger.Default.Register<PropertyChangedMessage<bool>>(this, m => ReceiveHasUpdatedMessage(m));
Messenger.Default.Register(this,m=>ReceiveHasUpdatedMessage(m));
然后在接收lambda中:
private void ReceiveHasUpdatedMessage(PropertyChangedMessage<bool> m)
{
// react accordingly.
}
private void ReceiveHasUpdatedMessage(PropertyChangedMessage m)
{
//作出相应的反应。
}
这只是MVVM Light提供的
Messenger
的一个简单用例。。你几乎可以做任何你想做的事。这里的前提是,使用这种方法可以使相关方不需要硬引用发射器 结合了大家非常有用的建议,我编写了以下代码。MVVM解决方案如上所述,尽管我没有对其进行测试。如果您不使用MVVM,这就是我所做的
UpdateManager类是相同的。Meta具有以下结构:
class Meta
{
private static bool hasUpdate = false;
public static event PropertyChangedEventHandler StaticPropertyChanged;
public static bool GetHasUpdate()
{
return hasUpdate;
}
public static void SetHasUpdate(bool value)
{
hasUpdate = value;
StaticNotifyPropertyChanged();
}
private static void StaticNotifyPropertyChanged([CallerMemberName] string propertyName = null)
{
StaticPropertyChanged?.Invoke(null, new PropertyChangedEventArgs(propertyName));
}
}
然后,对于我想知道这种变化的任何形式,我插入以下代码:
public partial class SomeForm : Window
{
public SomeForm()
{
InitializeComponent();
Meta.StaticPropertyChanged += MethodThatTriggersOnUpdate;
...
}
private void MethodThatTriggersOnUpdate(object sender, EventArgs e)
{
myImage.Dispatcher.BeginInvoke(
(Action)(() => myImage.Source = new BitmapImage(
new Uri("/MyProject;component/Images/myNewImage.gif", UriKind.Relative))));
}
...
}
尝试单例元,使用实例获取对象,并访问其道具。他们可以使用INotify或propdp's-如果propdps,那么当他们通过wpf的绑定系统将更改推送到绑定到他们的人时,您可以去掉更新程序静态属性更改是可行的,但它是不同的,并且您必须正确获得所有细节: