每当变量的值在 c# 中的 class 中发生变化时,都会在 main 中引发一个事件?
Raise an event in main whenever a variable's value changed in a class in c#?
我在 class 中有一个更改的事件,它是在变量值更改时触发的,但我不知道如何向我的 C# windows 窗体的主窗体发送通知,例如, 显示一个消息框来通知更改的值。我不想设置一个计时器来检查每一秒的响应。有什么更好的方法吗?
您可能正在寻找 INotifyPropertyChanged
,WPF 中的一种常见模式,但它也可用于 Windows 表单。文档页面上有一个相当大的示例:
https://msdn.microsoft.com/en-us/library/system.componentmodel.inotifypropertychanged(v=vs.110).aspx
class SomeClass : INotifyPropertyChanged
{
private int foo;
public event PropertyChangedEventHandler PropertyChanged;
public int Foo
{
get { return foo; }
set
{
if (foo == value)
return;
foo = value;
PropertyChanged("Foo");
}
}
protected void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
请注意,其中大部分变得更安全,样板文件更少 you use newer .NET features,例如 [CallerMemberName]
您应该用“属性”(Getter 和 Setter)来包装您的变量。
然后您可以在 "Setter" 中实施您自己的事件,或者您可以从 WPF 触发 属性 已更改事件(如果您使用的是 WPF)。
与其他帖子一样,您应该实施 INotifyPropertyChanged,但此外我还建议以下内容:
- 在您的 属性 的 setter 中检查分配给您的 属性 的值是否真的改变了 属性 的值。否则,您可能会经常触发通知更改。
- 您还应该实施 ISupportInitialize。通常,您触发 属性 changed 事件来通知您的主窗体数据已更改并需要保存。但是如果你从例如加载你的实例一个数据库, 属性 changed 事件也会触发,表明数据已经改变,从这个意义上讲这是不正确的。使用 ISupportInitialize,您可以告诉您的实例它们正在初始化并且它们不应触发通知 属性 已更改事件。
下面是一些示例代码:
class MyTest : INotifyPropertyChanged, ISupportInitialize
{
public event PropertyChangedEventHandler INotifyPropertyChanged.PropertyChanged;
public delegate void PropertyChangedEventHandler(object sender, PropertyChangedEventArgs e);
private bool _IsInitializing;
private bool _MyProperty;
public void BeginInit()
{
_IsInitializing = true;
}
public void EndInit()
{
_IsInitializing = false;
}
public bool MyProperty {
get { return _MyProperty; }
set {
if (_MyProperty == value)
return;
_MyProperty = value;
OnPropertyChanged("MyProperty");
}
}
private void OnPropertyChanged(string propertyName)
{
if (_IsInitializing)
return;
if (PropertyChanged != null) {
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
对于初始化,您将编写(以防止触发 属性 更改的事件):
MyTest thisTest = new MyTest();
thisTest.BeginInit();
thisTest.MyProperty = true;
thisTest.EndInit();
我在 class 中有一个更改的事件,它是在变量值更改时触发的,但我不知道如何向我的 C# windows 窗体的主窗体发送通知,例如, 显示一个消息框来通知更改的值。我不想设置一个计时器来检查每一秒的响应。有什么更好的方法吗?
您可能正在寻找 INotifyPropertyChanged
,WPF 中的一种常见模式,但它也可用于 Windows 表单。文档页面上有一个相当大的示例:
https://msdn.microsoft.com/en-us/library/system.componentmodel.inotifypropertychanged(v=vs.110).aspx
class SomeClass : INotifyPropertyChanged
{
private int foo;
public event PropertyChangedEventHandler PropertyChanged;
public int Foo
{
get { return foo; }
set
{
if (foo == value)
return;
foo = value;
PropertyChanged("Foo");
}
}
protected void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
请注意,其中大部分变得更安全,样板文件更少 you use newer .NET features,例如 [CallerMemberName]
您应该用“属性”(Getter 和 Setter)来包装您的变量。
然后您可以在 "Setter" 中实施您自己的事件,或者您可以从 WPF 触发 属性 已更改事件(如果您使用的是 WPF)。
与其他帖子一样,您应该实施 INotifyPropertyChanged,但此外我还建议以下内容:
- 在您的 属性 的 setter 中检查分配给您的 属性 的值是否真的改变了 属性 的值。否则,您可能会经常触发通知更改。
- 您还应该实施 ISupportInitialize。通常,您触发 属性 changed 事件来通知您的主窗体数据已更改并需要保存。但是如果你从例如加载你的实例一个数据库, 属性 changed 事件也会触发,表明数据已经改变,从这个意义上讲这是不正确的。使用 ISupportInitialize,您可以告诉您的实例它们正在初始化并且它们不应触发通知 属性 已更改事件。
下面是一些示例代码:
class MyTest : INotifyPropertyChanged, ISupportInitialize
{
public event PropertyChangedEventHandler INotifyPropertyChanged.PropertyChanged;
public delegate void PropertyChangedEventHandler(object sender, PropertyChangedEventArgs e);
private bool _IsInitializing;
private bool _MyProperty;
public void BeginInit()
{
_IsInitializing = true;
}
public void EndInit()
{
_IsInitializing = false;
}
public bool MyProperty {
get { return _MyProperty; }
set {
if (_MyProperty == value)
return;
_MyProperty = value;
OnPropertyChanged("MyProperty");
}
}
private void OnPropertyChanged(string propertyName)
{
if (_IsInitializing)
return;
if (PropertyChanged != null) {
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
对于初始化,您将编写(以防止触发 属性 更改的事件):
MyTest thisTest = new MyTest();
thisTest.BeginInit();
thisTest.MyProperty = true;
thisTest.EndInit();