我正在处理 C# Windows 窗体应用程序。我有一些表格,所有这些表格都对全局变量的值敏感。 [静态类的静态成员]
我不想在每个表单上运行一个计时器并检查这个变量。我希望这些表格对这个变量的值敏感,并且每个表格都执行自己的例程。
我该怎么办?有没有标准的方法来实现这些类型的算法?
在高级语言中你没有中断,但是你有事件。
因此,想象一下有一个类(甚至是静态类),让任何对该类中发生的某种事件感兴趣的人在该事件发生时得到通知。
该事件可以是任何东西,但通常与该类的状态变化有关,因此,改变 property 的值是一个可以通知任何感兴趣的人的事件。
让我们构建一个能够通知外部客户(您的表单)属性(不是简单字段)已更改的类。
public static class MyGlobalData
{
public static event PropertyChangedEventHandler PropertyChanged;
// Private internal value for flag1
private static bool _myStatusFlag1
// Public property that every client use to set or read the Flag1
public static bool StatusFlag1
{
get { return _myStatusFlag1; }
set
{
if (value != _myStatusFlag1)
{
_myStatusFlag1 = value;
NotifyPropertyChanged("StatusFlag1");
}
}
}
// Notify every client interested about the event just happened
private static void NotifyPropertyChanged(string propName)
{
var handler = PropertyChanged;
if (handler != null)
{
handler(null, new PropertyChangedEventArgs(propName));
}
}
}
所以,这个静态类包含你所有的静态变量(注意,它们不仅仅是一堆公共变量,而是一组属性,它们各自有 get 和 set 访问器。
此时,在每个有兴趣了解 StatusFlag1 何时更改其值的表单中,您需要添加此代码
public class Form1 : Form
{
public Form1()
{
// This is the key part. Append your listener method
// to the chain of methods that should be called
// when something changes on MyGlobalData.
MyGlobalData.PropertyChanged += ListenerOnForm1;
}
private void ListenerOnForm1(object sender, PropertyChangedEventArgs args)
{
// This is the property name (StatusFlag1)
Console.WriteLine(args.PropertyName);
// Now get the name of every static property in the class
var piInfo = typeof(MyGlobalData)
.GetProperties(BindingFlags.Public|BindingFlags.Static);
// Find the property with the specific name received
var p = piInfo.FirstOrDefault(i => i.Name == args.PropertyName);
// Do whatever you need to do with the property value
if(p != null)
Console.WriteLine(p.GetValue(null));
}
}
当然你可以通过一些简单的测试来简化上面的代码
if(args.PropertyName == "StatusFlag1")
if(MyGlobalData.StatusFlag1 == true)
.... do whatever you need with it
这是正常情况。有时我们需要使用定时器之类的东西。 (这称为 Pooling 方法)。有时我们需要中断(这在
Event
术语中称为 C#
)。
所以。正如你所说,我们有一个静态类:
internal static class StaticClass
{
public delegate void SomethingHappendEventHandler(object sender, EventPayload e);
public static event SomethingHappendEventHandler SomethingHappendEvent;
public class EventPayload
{
public string Message { get; set; }
}
public static async Task BroadCastAnEvent(string message)
{
SomethingHappendEvent?.Invoke(null, new EventPayload()
{
Message = message
// Extra info should be defined in payload class if you want to pass them.
});
}
}
我们有一些
Form
想要抓住那些Event
。对于每一个表格,你都应该这样做:
public ChildForm()
{
InitializeComponent();
StaticClass.SomethingHappendEvent += StaticClass_SomethingHappendEvent;
}
private void StaticClass_SomethingHappendEvent(object sender, StaticClass.EventPayload e)
{
MessageBox.Show(e.Message);
}
您可以拨打:
StaticClass.BroadCastAnEvent("My message");
无论您在哪里,所有这些表格都会收到此消息,并且他们能够使用它。