C# WPF INotifyPropertyChanged 不更新表单

C# WPF INotifyPropertyChanged not updating form

我正在尝试使用基于用户输入的一些计算来实现一个表单。使用 MVVM 模式,特别是 INotifyPropertyChanged。

当用户在文本框中输入一个值时,一切正常,计算例程被触发,表单随结果更新。

然而,当输入从代码隐藏更改时,Inotify 例程会触发,计算完成,但绑定的控件不会更新。

我有两个问题:

  1. 在框架内使用页面,我想在页面更改时触发刷新
  2. 导入以前保存在 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 的实例,则可能会影响正确的操作。
因此,您必须确保此变量(属性 或字段?)仅在通知其更改时才被访问。