【问题标题】:Fire event on value change of double双倍值变化的火灾事件
【发布时间】:2013-06-09 05:40:55
【问题描述】:

我在自定义类中使用INotifyPropertyChanged 在变量更改时触发事件,但我想知道是否有一种简单的方法可以在单个变量更改时触发事件,例如双变量。

例如,在 WPF 应用程序中,如果我有

private double a;

MainWindow.xaml.cs 中,是否有一种简单 方法可以在a 被分配到的任何时候触发事件?

【问题讨论】:

    标签: c# wpf events inotifypropertychanged


    【解决方案1】:

    字段没有任何跟踪更改的方法。为了使它工作,它需要是一个属性,并且需要一些东西来处理跟踪。这就是INotifyPropertyChanged 接口的用途。

    跟踪此值更改的正常方法是在您的类中实现INotifyPropertyChanged

    【讨论】:

      【解决方案2】:

      如果我理解正确,您需要为 a 创建一个 Setter,然后触发 propertyychange 事件/自定义事件,而不是将 a 封装到一个类中。

      类似这样的:

      private double a;
      
          public double A
          {
              get { return a; }
              set { a = value;
                    firepropertyChange(a);
                  }
          }
      

      【讨论】:

        【解决方案3】:

        (取决于),如果您通过属性包装您的变量访问并在更改时触发您的事件,并确保对该变量的所有访问都是通过该属性,例如

        private double a;
        
        public double PropertyA
        {
            get
            {
                return a;
            }
            set
            {
                // set value and fire event only when value is changed
                // if we want to know when value set is the same then remove if condition
                if (a != value)
                {
                    a = value;
                    PropertyChanged("PropertyA");
                }
            }
        }
        
        // when changing a, make sure to use the property instead...
        PropertyA = 5.2;
        

        ...否则,没有

        【讨论】:

        • 提供字符串参数是一种不好的风格和非通用的。您应该提供A 本身
        • @StefanoL 您是部分正确的,尽管在这种情况下还不错。见msdn.microsoft.com/en-us/library/ms133020.aspx,也是硬编码值,用户输入有问题
        【解决方案4】:

        如果您使用的是 C# 5.0,您可以通过这种方式使用 CallerMemberName 属性:

        class MyData : INotifyPropertyChanged
        {
            private string _name;
            public string Name
            {
                get { return _name; }
                set
                {
                    _name = value;
                    RaisePropertyChanged();
                }
            }
        
            private string _anotherProperty;
            public string AnotherProperty
            {
                get { return _anotherProperty; }
                set
                {
                    _anotherProperty = value;
                    RaisePropertyChanged();
                }
            }
        
            public event PropertyChangedEventHandler PropertyChanged;
            private void RaisePropertyChanged([CallerMemberName] string caller = "")
            {
                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs(caller));
                }
            }
        }
        

        如您所见,您只需为每个属性在set 中调用RaisePropertyChanged();,而无需一遍又一遍地输入属性名称。

        另一种方法是定义一个ModelBase 类:

        class ModelBase : INotifyPropertyChanged
        {
            public event PropertyChangedEventHandler PropertyChanged;
        
            protected void Set<T>(ref T field, T value, [CallerMemberName] string propertyName = "")
            {
                if (!Object.Equals(field, value))
                {
                    field = value;
        
                    if (PropertyChanged != null)
                        PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
                }
            }
        }
        

        然后从ModelBase推导出你的模型:

        class Conf : ModelBase
        {
            NodeType _nodeType = NodeType.Type1;
        
            public NodeType NodeType
            {
                get { return _nodeType; }
                set { Set(ref _nodeType, value); }
            }
        }
        

        【讨论】:

          猜你喜欢
          • 2020-03-05
          • 1970-01-01
          • 1970-01-01
          • 2016-11-23
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多