IT评测·应用市场-qidao123.com

标题: C# Winform 实现静态变量属性的值变了,触发事件,类似WPF的双向绑定 [打印本页]

作者: 北冰洋以北    时间: 2025-2-12 15:20
标题: C# Winform 实现静态变量属性的值变了,触发事件,类似WPF的双向绑定
在C# WinForms中,虽然没有像WPF那样内置的双向绑定机制,但你可以通过事件和属性封装来实现类似的功能。具体来说,你可以在静态属性的set访问器中触发一个自定义事件,然后在必要的地方订阅这个事件,以便在属性值发生变化时执行相应的操纵。
全局状态的隐患
内存泄漏风险
Form 窗体释放后,记得取消订阅
  1. public void MyForm_Closing(object sender, FormClosingEventArgs e)
  2. {
  3.    //显式取消订阅
  4.    GlobalEvents.SomeGlobalEvent -= HandleEvent;
  5. }
  6. //或者
  7. public void Dispose()
  8. {
  9.    //显式取消订阅
  10.    GlobalEvents.SomeGlobalEvent -= HandleEvent;
  11. }
复制代码
以下是一个简单的示例,展示了如何实现这一功能:
  1. using System;
  2. using System.Windows.Forms;
  3. public static class MyStaticClass
  4. {
  5.     // 定义事件
  6.     public static event EventHandler<EventArgs> MyPropertyChanged;
  7.     private static string _myProperty;
  8.     public static string MyProperty
  9.     {
  10.         get { return _myProperty; }
  11.         set
  12.         {
  13.             if (_myProperty != value)
  14.             {
  15.                 _myProperty = value;
  16.                 // 触发事件
  17.                 OnMyPropertyChanged();
  18.             }
  19.         }
  20.     }
  21.     // 触发事件的方法
  22.     private static void OnMyPropertyChanged()
  23.     {
  24.         MyPropertyChanged?.Invoke(null, EventArgs.Empty);
  25.     }
  26. }
  27. public class MyForm : Form
  28. {
  29.     private Label myLabel;
  30.     public MyForm()
  31.     {
  32.         myLabel = new Label();
  33.         myLabel.Text = "Initial Value";
  34.         myLabel.Location = new System.Drawing.Point(10, 10);
  35.         this.Controls.Add(myLabel);
  36.         // 订阅事件
  37.         MyStaticClass.MyPropertyChanged += MyStaticClass_MyPropertyChanged;
  38.     }
  39.     // 事件处理程序
  40.     private void MyStaticClass_MyPropertyChanged(object sender, EventArgs e)
  41.     {
  42.         // 当属性值变化时,更新Label的文本
  43.         myLabel.Text = MyStaticClass.MyProperty;
  44.     }
  45.     [STAThread]
  46.     public static void Main()
  47.     {
  48.         Application.EnableVisualStyles();
  49.         Application.Run(new MyForm());
  50.     }
  51. }
复制代码
使用示例:
你可以在其他地方修改 MyStaticClass.MyProperty 的值,例如:
  1. MyStaticClass.MyProperty = "New Value";
复制代码
注意事项:
通过这种方式,你可以在WinForms中实现类似WPF的双向绑定结果。
这里使用的是 EventHandler 泛型委托,此中 TEventArgs 是 EventArgs 类型(或派生类型)。这种定义方式已经隐式地使用了委托,因此不必要显式地定义一个新的委托类型。
如果显式定义委托,好处是什么?
1. 自定义事件参数:
如果你必要传递更多信息(不但仅是 sender 和 EventArgs),可以定义一个自定义的事件参数类,并为其定义一个专门的委托。
  1. public class MyPropertyChangedEventArgs : EventArgs
  2. {
  3.     public string OldValue { get; }
  4.     public string NewValue { get; }
  5.     public MyPropertyChangedEventArgs(string oldValue, string newValue)
  6.     {
  7.         OldValue = oldValue;
  8.         NewValue = newValue;
  9.     }
  10. }
  11. // 定义自定义委托
  12. public delegate void MyPropertyChangedEventHandler(object sender, MyPropertyChangedEventArgs e);
  13. // 使用自定义委托定义事件
  14. public static event MyPropertyChangedEventHandler MyPropertyChanged;
复制代码
如许,事件处置处罚步伐可以吸收到更多信息(如旧值和新值)。
2. 提高代码可读性:
显式定义委托可以让代码更具可读性,尤其是当事件的用途非常明白时。
  1. public delegate void MyPropertyChangedDelegate(string newValue);
  2. public static event MyPropertyChangedDelegate MyPropertyChanged;
复制代码
这种方式更直观地表达了事件的用途。
3.灵活性:
自定义委托可以定义更灵活的参数列表,而不但限于 object sender, EventArgs e 的标准模式。
例如,你可以定义一个没有 sender 参数的事件:
  1. public delegate void MyPropertyChangedDelegate(string newValue);
  2. public static event MyPropertyChangedDelegate MyPropertyChanged;
复制代码
显式定义委托

以下是显式定义委托的完备示例:
  1. using System;
  2. using System.Windows.Forms;
  3. public static class MyStaticClass
  4. {
  5.     // 定义自定义委托
  6.     public delegate void MyPropertyChangedDelegate(string newValue);
  7.     // 定义事件
  8.     public static event MyPropertyChangedDelegate MyPropertyChanged;
  9.     private static string _myProperty;
  10.     public static string MyProperty
  11.     {
  12.         get { return _myProperty; }
  13.         set
  14.         {
  15.             if (_myProperty != value)
  16.             {
  17.                 string oldValue = _myProperty;
  18.                 _myProperty = value;
  19.                 // 触发事件
  20.                 OnMyPropertyChanged(value);
  21.             }
  22.         }
  23.     }
  24.     // 触发事件的方法
  25.     private static void OnMyPropertyChanged(string newValue)
  26.     {
  27.         MyPropertyChanged?.Invoke(newValue);
  28.     }
  29. }
  30. public class MyForm : Form
  31. {
  32.     private Label myLabel;
  33.     public MyForm()
  34.     {
  35.         myLabel = new Label();
  36.         myLabel.Text = "Initial Value";
  37.         myLabel.Location = new System.Drawing.Point(10, 10);
  38.         this.Controls.Add(myLabel);
  39.         // 订阅事件
  40.         MyStaticClass.MyPropertyChanged += MyStaticClass_MyPropertyChanged;
  41.     }
  42.     // 事件处理程序
  43.     private void MyStaticClass_MyPropertyChanged(string newValue)
  44.     {
  45.         // 当属性值变化时,更新Label的文本
  46.         myLabel.Text = newValue;
  47.     }
  48.     [STAThread]
  49.     public static void Main()
  50.     {
  51.         Application.EnableVisualStyles();
  52.         Application.Run(new MyForm());
  53.     }
  54. }
复制代码
总结
使用 EventHandler 的好处:
显式定义委托的好处:
在现实开发中,选择哪种方式取决于具体需求。如果只是简单的值变化关照,使用 EventHandler 就充足了;如果必要更复杂的事件参数或更高的灵活性,则可以显式定义委托。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 IT评测·应用市场-qidao123.com (https://dis.qidao123.com/) Powered by Discuz! X3.4