Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#WPF InotifyProperty已更改,未更新表单_C#_Wpf_Inotifypropertychanged - Fatal编程技术网

C#WPF InotifyProperty已更改,未更新表单

C#WPF InotifyProperty已更改,未更新表单,c#,wpf,inotifypropertychanged,C#,Wpf,Inotifypropertychanged,我试图实现一个表单,其中包含一些基于用户输入的计算。使用MVVM模式,特别是INotifyPropertyChanged 当用户在文本框中输入一个值,计算例程启动,表单更新结果时,所有这些都可以正常工作 但是,当输入从codebehind更改时,Inotify例程启动,计算完成,但绑定控件不更新 我有两个问题: 使用框架内的页面,我希望在页面更改时触发刷新 导入以前保存在Xml文件中的数据。同样,例程会激发,但不会更新窗体的绑定控件 我附上了代码的浓缩版本,但我认为这并不是问题所在。注意,我使用

我试图实现一个表单,其中包含一些基于用户输入的计算。使用MVVM模式,特别是INotifyPropertyChanged

当用户在文本框中输入一个值,计算例程启动,表单更新结果时,所有这些都可以正常工作

但是,当输入从codebehind更改时,Inotify例程启动,计算完成,但绑定控件不更新

我有两个问题:

  • 使用框架内的页面,我希望在页面更改时触发刷新
  • 导入以前保存在Xml文件中的数据。同样,例程会激发,但不会更新窗体的绑定控件
  • 我附上了代码的浓缩版本,但我认为这并不是问题所在。注意,我使用的是单例类

    谢谢

    ===============

    //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)));
    
            }
        }
    }
    
    注意,我使用的是单例类

    此代码中没有错误。 但您可能使用不正确。 为了避免意外的使用错误,我建议您更改实现:

    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的实例更改,则正确的操作可能会受到影响。

    因此,您必须确保只有在通知该变量(属性或字段?)的更改后才能访问该变量。

    这可能会有所帮助。在绑定到Pressure属性的UI元素上,尝试以下更新SourceTrigger=PropertyChanged。。例如,请注意,
    nameof(Pressure)
    绝对不应位于OnPropertyChanged方法内。应该有一个字符串参数,并且应该像调用OnPropertyChanged(nameof(Pressure))一样调用该方法@Saurav所说的不正确
    UpdateSourceTrigger=PropertyChanged
    与INotifyPropertyChanged接口的PropertyChanged事件无关。它控制其他绑定方向(从目标到源)的工作方式,对单向绑定(仅从源到目标)没有任何影响。此外,当一个输入属性发生更改时,它会更新许多其他绑定结果,这在我提供的代码示例中没有显示。“这比INotifyPropertyChanged实现更容易…”对于多个属性来说可能不正确,因为您可以只编写
    PropertyChanged?.Invoke(这是新的PropertyChangedEventArgs(nameof(Pressure)))
    而不是
    压力更改?.Invoke(this,EventArgs.Empty)
    ,但只声明一个事件,而不是每个属性声明一个事件。不需要OnPropertyChanged方法。当然,您必须声明接口实现。好吧,对于两个,它不是真的:-)错误不在类的实现中。如果您创建了多个
    UcIOChanged
    实例,则可能会发生意外错误。这正是我在示例中展示的内容。使用另一个事件是次要的,并不重要。这只是补充信息。隐藏实例构造函数很重要。如果这没有帮助,那么我们需要弄清楚如何使用这个类。这需要一个再现问题的解决方案的最小示例。此外,请务必注意,在计算逻辑中,您应该始终仅通过
    UcIOChanged.Instance
    实例访问
    s.Pressure
    变量。要在XAML中获取实例,必须使用x:Static标记扩展。在我的示例中,请仔细查看如何获取绑定的源代码。也可以为数据上下文或某些其他属性获取它。