在C# WinForms中,虽然没有像WPF那样内置的双向绑定机制,但你可以通过事件和属性封装来实现类似的功能。具体来说,你可以在静态属性的set访问器中触发一个自定义事件,然后在需要的地方订阅这个事件,以便在属性值发生变化时执行相应的操作。

以下是一个简单的示例,展示了如何实现这一功能:

using System;
using System.Windows.Forms; public static class MyStaticClass
{
// 定义事件
public static event EventHandler<EventArgs> MyPropertyChanged; private static string _myProperty;
public static string MyProperty
{
get { return _myProperty; }
set
{
if (_myProperty != value)
{
_myProperty = value;
// 触发事件
OnMyPropertyChanged();
}
}
} // 触发事件的方法
private static void OnMyPropertyChanged()
{
MyPropertyChanged?.Invoke(null, EventArgs.Empty);
}
} public class MyForm : Form
{
private Label myLabel; public MyForm()
{
myLabel = new Label();
myLabel.Text = "Initial Value";
myLabel.Location = new System.Drawing.Point(10, 10);
this.Controls.Add(myLabel); // 订阅事件
MyStaticClass.MyPropertyChanged += MyStaticClass_MyPropertyChanged;
} // 事件处理程序
private void MyStaticClass_MyPropertyChanged(object sender, EventArgs e)
{
// 当属性值变化时,更新Label的文本
myLabel.Text = MyStaticClass.MyProperty;
} [STAThread]
public static void Main()
{
Application.EnableVisualStyles();
Application.Run(new MyForm());
}
}

使用示例:

你可以在其他地方修改 MyStaticClass.MyProperty 的值,例如:

MyStaticClass.MyProperty = "New Value";

注意事项:

  • 由于 MyProperty 是静态的,它的值在整个应用程序生命周期内是共享的。
  • 如果你需要在多个窗体或控件之间共享状态,这种方法是有效的。

通过这种方式,你可以在WinForms中实现类似WPF的双向绑定效果。

这里使用的是 EventHandler<TEventArgs> 泛型委托,其中 TEventArgsEventArgs 类型(或派生类型)。这种定义方式已经隐式地使用了委托,因此不需要显式地定义一个新的委托类型。

如果显式定义委托,好处是什么?

1. 自定义事件参数:

如果你需要传递更多信息(不仅仅是 sender 和 EventArgs),可以定义一个自定义的事件参数类,并为其定义一个专门的委托。

public class MyPropertyChangedEventArgs : EventArgs
{
public string OldValue { get; }
public string NewValue { get; } public MyPropertyChangedEventArgs(string oldValue, string newValue)
{
OldValue = oldValue;
NewValue = newValue;
}
} // 定义自定义委托
public delegate void MyPropertyChangedEventHandler(object sender, MyPropertyChangedEventArgs e); // 使用自定义委托定义事件
public static event MyPropertyChangedEventHandler MyPropertyChanged;

这样,事件处理程序可以接收到更多信息(如旧值和新值)。

2. 提高代码可读性:

显式定义委托可以让代码更具可读性,尤其是当事件的用途非常明确时。

public delegate void MyPropertyChangedDelegate(string newValue);

public static event MyPropertyChangedDelegate MyPropertyChanged;

这种方式更直观地表达了事件的用途。

3.灵活性:

自定义委托可以定义更灵活的参数列表,而不仅限于 object sender, EventArgs e 的标准模式。

例如,你可以定义一个没有 sender 参数的事件:

public delegate void MyPropertyChangedDelegate(string newValue);

public static event MyPropertyChangedDelegate MyPropertyChanged;

显式定义委托

以下是显式定义委托的完整示例:

using System;
using System.Windows.Forms; public static class MyStaticClass
{
// 定义自定义委托
public delegate void MyPropertyChangedDelegate(string newValue); // 定义事件
public static event MyPropertyChangedDelegate MyPropertyChanged; private static string _myProperty;
public static string MyProperty
{
get { return _myProperty; }
set
{
if (_myProperty != value)
{
string oldValue = _myProperty;
_myProperty = value;
// 触发事件
OnMyPropertyChanged(value);
}
}
} // 触发事件的方法
private static void OnMyPropertyChanged(string newValue)
{
MyPropertyChanged?.Invoke(newValue);
}
} public class MyForm : Form
{
private Label myLabel; public MyForm()
{
myLabel = new Label();
myLabel.Text = "Initial Value";
myLabel.Location = new System.Drawing.Point(10, 10);
this.Controls.Add(myLabel); // 订阅事件
MyStaticClass.MyPropertyChanged += MyStaticClass_MyPropertyChanged;
} // 事件处理程序
private void MyStaticClass_MyPropertyChanged(string newValue)
{
// 当属性值变化时,更新Label的文本
myLabel.Text = newValue;
} [STAThread]
public static void Main()
{
Application.EnableVisualStyles();
Application.Run(new MyForm());
}
}

总结

使用 EventHandler 的好处:

  • 简单、标准化,适合大多数场景。
  • 符合 .NET 的事件模式(object sender, EventArgs e)。

显式定义委托的好处:

  • 更灵活,可以自定义参数列表。
  • 提高代码可读性和表达力。
  • 适合需要传递更多信息的场景。

在实际开发中,选择哪种方式取决于具体需求。如果只是简单的值变化通知,使用 EventHandler 就足够了;如果需要更复杂的事件参数或更高的灵活性,则可以显式定义委托。

C# Winform 实现静态变量属性的值变了,触发事件,类似WPF的双向绑定的更多相关文章

  1. C#实现某一属性值变化时触发事件

    在我们做工业软件中,经常会遇到要实时监控某一点,在这个点变化时去做一些事情 放入程序里呢,就是要实时监控某一属性的值,当值发生变化时触发事件,其核心就是借助属性的Set方法,来判断当前set的值是否与 ...

  2. DataGridView中DataGridViewComboBoxColumn的一些相关应用(一)让其值改变时触发事件-转

    转自  https://maodaili.de/mao.php?u=a%2FMrbEvUE8PnCuc7FrhJi0Rqd3kmOBHPZUbcJ1c2hbJUK0RYWpAf4lhIOddItP%2 ...

  3. -1-2 java 面向对象基本概念 封装继承多态 变量 this super static 静态变量 匿名对象 值传递 初始化过程 代码块 final关键字 抽象类 接口 区别 多态 包 访问权限 内部类 匿名内部类 == 与 equal

    java是纯粹的面向对象的语言 也就是万事万物皆是对象 程序是对象的集合,他们通过发送消息来相互通信 每个对象都有自己的由其他的对象所构建的存储,也就是对象可以包含对象 每个对象都有它的类型  也就是 ...

  4. Vu3.x如何给v-for循环出来的输入框绑定v-mode的值,以及实现父子组件传值、双向绑定

    观前须知:本人演示使用的input是自己手敲的,如果使用的是element-ui等表单组建的input框请选择性参考,不保证我的方法对你们也完全有效. 父组件代码: 这里我的MiniInput是以组件 ...

  5. Vue框架-03:JS的几种循环方式,Key值的解释,数组/对象的检测与更新,input事件,v-model数据双向绑定,过滤案例,事件修饰符,按键修饰符,表单控制

    目录 前端开发之Vue框架 一.JS循环的几种方式 1.v-for可循环的变量 2.js的循环方式 二.Key值的解释 三.数组.对象的检测与更新 四.input事件 五.v-model双向数据绑定 ...

  6. 研究一下FBrush,它是从TWinControl才有的属性(可能是因为需要句柄)——发现{$R *.dfm}在运行期执行,而且很有深意,读到属性后赋值还会触发事件,这些无法在VCL代码里直接看到

    定义和创建: TWinControl = class(TControl) private FBrush: TBrush; end; constructor TWinControl.Create(AOw ...

  7. Linux c readdir是非线程安全,需用readdir_r,要注意用静态变量当做返回值的函数的非线程安全性

    readdir函数: struct dirent *readdir(DIR *dirp); The  data  returned by readdir() may be overwritten by ...

  8. Java---类加载机制,构造方法,静态变量,(静态)代码块,父类,变量加载顺序

    直接上代码: 代码1: public class ConstroctTest { private static ConstroctTest test = new ConstroctTest(); // ...

  9. PHP---------PHP函数里面的static静态变量

    工作一年了,一年里很少用到static这个关键词,不管是类里面还是方法里面基本都没怎么用过.平时看到类里面有这个都没什么好奇的,今天在函数里面看到了这个,就去百度了一下. <?phpfuncti ...

  10. Android中静态变量的生命周期

    静态变量的生命周期,起始于类的加载,终止于类的释放.什么时候类会加载呢?我们知道,在app打开时,会创建一个进程,然后初始化一个dvm的实例,负责类的加载释放 和 垃圾回收等.换句话说,在进程创建之后 ...

随机推荐

  1. 安装cnpm时报错

    报错:npm WARN deprecated socks@1.1.10: If using 2.x branch, please upgrade to at least 2.1.6 to avoid ...

  2. Centos7 安装python3与python2.7 共存

    前言 在centos7服务器上,linux系统默认安装有python2.7,这是系统服务等会依赖到的,所以系统的python2.7是不可以卸载的,避免系统出现问题.那么问题就来了,我们现在使用的pyt ...

  3. vue3-setup中使用响应式

    基本类型的响应式数据 在 Vue 3 中,ref是一个函数,用于创建响应式的数据.它主要用于处理基本类型(如数字.字符串.布尔值等)的数据响应式 当我们调用 ref 函数时,会返回一个包含一个 .va ...

  4. uni-app 主题切换

    1.前言 功能介绍:提供个性化的展示方案给用户,用户可以选择喜欢的主题色,让App使用该主题色进行渲染 功能实现:主要分为2个模块,一,选择主题色并存储,二,读取选择的主题色,使用该颜色对部分内容进行 ...

  5. .NET Core 锁(Lock)底层原理浅谈

    CPU原子操作 原子操作,指一段逻辑要么全部成功,要么全部失败.概念上类似数据库事物(Transaction). CPU能够保证单条汇编的原子性,但不保证多条汇编的原子性 那么在这种情况下,那么CPU ...

  6. 【二分+前缀和+后缀和】codeforces 2026 D. Sums of Segments

    题目 https://codeforces.com/problemset/problem/2026/D 题意 第一行输入一个正整数 \(n(1 \leq n \leq 3e5)\),第二行输入 \(n ...

  7. Linux驱动开发笔记(七):操作系统MMU介绍,操作系统操作寄存器的原理和Demo

    前言   做过单片机的都知道,写驱动是直接代码设置和读取寄存器来控制外设实现基本的驱动功能,而linux操作系统上是由MMU(内存管理单元)来控制,MMU实现了虚拟地址与芯片物理地址的对应,设置和获取 ...

  8. Swagger2学习——@ApiImplicitParams注解

    @ApiImplicitParams:用在请求的方法上,表示一组参数说明 @ApiImplicitParam:用在@ApiImplicitParams注解中,指定一个请求参数的各个方面 name:参数 ...

  9. thinkphp6.0封装数据库及缓存模型

    项目中的thinkphp6.0\app\common\Model.php 1 <?php 2 /** 3 * 数据库及缓存模型 4 */ 5 namespace app\common; 6 7 ...

  10. Qt通用方法及类库1

    函数名 //桌面宽度高度 static int deskWidth(); static int deskHeight(); //程序文件名称+当前所在路径 static QString appName ...