C# WPF INotifyPropertyChanged 不更新表单
C# WPF INotifyPropertyChanged not updating form
我正在尝试使用基于用户输入的一些计算来实现一个表单。使用 MVVM 模式,特别是 INotifyPropertyChanged。
当用户在文本框中输入一个值时,一切正常,计算例程被触发,表单随结果更新。
然而,当输入从代码隐藏更改时,Inotify 例程会触发,计算完成,但绑定的控件不会更新。
我有两个问题:
- 在框架内使用页面,我想在页面更改时触发刷新
- 导入以前保存在 Xml 文件中的数据。例程再次触发,但没有更新窗体的绑定控件。
我附上了代码的精简版,但我认为这不是真正的问题。注意我使用的是单例 class.
谢谢
===============
//INotify code
using s = Calc.Models.GlobalStrings;
namespace Calc.ViewModels.INotify
{
public class UcIOChanged : INotifyPropertyChanged
{
private static UcIOChanged instance;
public UcIOChanged() { }
//Make the class is a singleton
public static UcIOChanged Instance
{
get
{
if (instance == null)
{
instance = new UcIOChanged();
}
return instance;
}
}
public event PropertyChangedEventHandler PropertyChanged;
public string Pressure
{
get
{
return s.Pressure;
}
set
{
s.Pressure = value; OnPropertyChanged();
}
}
public void OnPropertyChanged()
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Pressure)));
}
}
}
Note I am using a singleton class.
这段代码没有错误。
但你可能使用不当。
为避免意外使用错误,我建议您更改实现:
public class UcIOChanged
{
// Hide the constructor to avoid
// accidentally creating other instances.
private UcIOChanged() {}
//Make the class is a singleton
public static UcIOChanged Instance { get; } = new UcIOChanged();
public string Pressure
{
get
{
return s.Pressure;
}
set
{
if (!Equals(s.Pressure, value))
{
s.Pressure = value;
PressureChanged?.Invoke(this, EventArgs.Empty);
}
}
}
// The event of the same name.
// It's easier for one or two properties
// than the INotifyPropertyChanged implementation.
public event EventHandler PressureChanged;
}
使用:
<TextBox Text="{Binding Pressure, Source={x:Static local:UcIOChanged.Instance}}"/>
P.S. 如果您在代码中的某处更改 s.Pressure
而不是通过 UcIOChanged.Instance 的实例,则可能会影响正确的操作。
因此,您必须确保此变量(属性 或字段?)仅在通知其更改时才被访问。
我正在尝试使用基于用户输入的一些计算来实现一个表单。使用 MVVM 模式,特别是 INotifyPropertyChanged。
当用户在文本框中输入一个值时,一切正常,计算例程被触发,表单随结果更新。
然而,当输入从代码隐藏更改时,Inotify 例程会触发,计算完成,但绑定的控件不会更新。
我有两个问题:
- 在框架内使用页面,我想在页面更改时触发刷新
- 导入以前保存在 Xml 文件中的数据。例程再次触发,但没有更新窗体的绑定控件。
我附上了代码的精简版,但我认为这不是真正的问题。注意我使用的是单例 class.
谢谢
===============
//INotify code
using s = Calc.Models.GlobalStrings;
namespace Calc.ViewModels.INotify
{
public class UcIOChanged : INotifyPropertyChanged
{
private static UcIOChanged instance;
public UcIOChanged() { }
//Make the class is a singleton
public static UcIOChanged Instance
{
get
{
if (instance == null)
{
instance = new UcIOChanged();
}
return instance;
}
}
public event PropertyChangedEventHandler PropertyChanged;
public string Pressure
{
get
{
return s.Pressure;
}
set
{
s.Pressure = value; OnPropertyChanged();
}
}
public void OnPropertyChanged()
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Pressure)));
}
}
}
Note I am using a singleton class.
这段代码没有错误。 但你可能使用不当。 为避免意外使用错误,我建议您更改实现:
public class UcIOChanged
{
// Hide the constructor to avoid
// accidentally creating other instances.
private UcIOChanged() {}
//Make the class is a singleton
public static UcIOChanged Instance { get; } = new UcIOChanged();
public string Pressure
{
get
{
return s.Pressure;
}
set
{
if (!Equals(s.Pressure, value))
{
s.Pressure = value;
PressureChanged?.Invoke(this, EventArgs.Empty);
}
}
}
// The event of the same name.
// It's easier for one or two properties
// than the INotifyPropertyChanged implementation.
public event EventHandler PressureChanged;
}
使用:
<TextBox Text="{Binding Pressure, Source={x:Static local:UcIOChanged.Instance}}"/>
P.S. 如果您在代码中的某处更改 s.Pressure
而不是通过 UcIOChanged.Instance 的实例,则可能会影响正确的操作。
因此,您必须确保此变量(属性 或字段?)仅在通知其更改时才被访问。