5.属性变化通知

属性变化通知
Prism框架提供了BindableBase类,用于做数据处理(例如属性的变化通知等)。

五种属性变化通知方式

通过继承BindableBase类,可以更加便捷地在WPF中实现属性变化通知,具体有如下五种方式。
其中前三种没啥特殊的,第四种方式可以在属性变化时,通知其他属性的绑定控件;而第五种方式则可以在属性发生变化后调用指定的函数。
测试后只有第二种和第三种能用,其他的都不能用,看了下BindableBase源码应该是底层缓存值和设置值对比的问题,还没输入研究

 

测试代码

public class MainViewModel : BindableBase
{
    private string _value;

    public string Value123
    {
        get => _value;
        set
        {
            _value = value;
            // 第一种方式【有问题】
            SetProperty(ref _value, value);

            // 第二种方式[没问题]
            //this.OnPropertyChanged(new System.ComponentModel.PropertyChangedEventArgs("Value123"));

            // 第三种方式[没问题]
            //this.RaisePropertyChanged();

            // 第四种方式:可以通知另一个属性【有问题】
            //SetProperty(ref _value, value, "Value1231");

            // 第五种方式【有问题】
            //SetProperty(ref _value, value, OnValueChanged);
            //————————————————
            //版权声明:本文为CSDN博主「SchuylerEX」的原创文章,遵循CC 4.0 BY - SA版权协议,转载请附上原文出处链接及本声明。
            //原文链接:https://blog.csdn.net/jjailsa/article/details/135708375
        }
    }
 
    private void OnValueChanged()
    {
        //属性成功变化后的执行函数
    }
}

UI代码

 

  <TextBox HorizontalAlignment="Left" Height="58" Margin="156,159,0,0" TextWrapping="Wrap" Text="{Binding Value123, UpdateSourceTrigger=PropertyChanged , Mode=TwoWay}" VerticalAlignment="Top" Width="133"/>
  <TextBox HorizontalAlignment="Left" Height="58" Margin="367,159,0,0" TextWrapping="Wrap" Text="{Binding Value123, UpdateSourceTrigger=PropertyChanged , Mode=TwoWay}" VerticalAlignment="Top" Width="229"/>

 

 

 

 

BindableBase的源码

 1 /// <summary>
 2 /// Implementation of <see cref="INotifyPropertyChanged"/> to simplify models.
 3 /// </summary>
 4 public abstract class BindableBase : INotifyPropertyChanged
 5 {
 6     /// <summary>
 7     /// Occurs when a property value changes.
 8     /// </summary>
 9     public event PropertyChangedEventHandler PropertyChanged;
10 
11     /// <summary>
12     /// Checks if a property already matches a desired value. Sets the property and
13     /// notifies listeners only when necessary.
14     /// </summary>
15     /// <typeparam name="T">Type of the property.</typeparam>
16     /// <param name="storage">Reference to a property with both getter and setter.</param>
17     /// <param name="value">Desired value for the property.</param>
18     /// <param name="propertyName">Name of the property used to notify listeners. This
19     /// value is optional and can be provided automatically when invoked from compilers that
20     /// support CallerMemberName.</param>
21     /// <returns>True if the value was changed, false if the existing value matched the
22     /// desired value.</returns>
23     protected virtual bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
24     {
25         if (EqualityComparer<T>.Default.Equals(storage, value)) return false;
26 
27         storage = value;
28         RaisePropertyChanged(propertyName);
29 
30         return true;
31     }
32 
33     /// <summary>
34     /// Checks if a property already matches a desired value. Sets the property and
35     /// notifies listeners only when necessary.
36     /// </summary>
37     /// <typeparam name="T">Type of the property.</typeparam>
38     /// <param name="storage">Reference to a property with both getter and setter.</param>
39     /// <param name="value">Desired value for the property.</param>
40     /// <param name="propertyName">Name of the property used to notify listeners. This
41     /// value is optional and can be provided automatically when invoked from compilers that
42     /// support CallerMemberName.</param>
43     /// <param name="onChanged">Action that is called after the property value has been changed.</param>
44     /// <returns>True if the value was changed, false if the existing value matched the
45     /// desired value.</returns>
46     protected virtual bool SetProperty<T>(ref T storage, T value, Action onChanged, [CallerMemberName] string propertyName = null)
47     {
48         if (EqualityComparer<T>.Default.Equals(storage, value)) return false;
49 
50         storage = value;
51         onChanged?.Invoke();
52         RaisePropertyChanged(propertyName);
53 
54         return true;
55     }
56 
57     /// <summary>
58     /// Raises this object's PropertyChanged event.
59     /// </summary>
60     /// <param name="propertyName">Name of the property used to notify listeners. This
61     /// value is optional and can be provided automatically when invoked from compilers
62     /// that support <see cref="CallerMemberNameAttribute"/>.</param>
63     protected void RaisePropertyChanged([CallerMemberName] string propertyName = null)
64     {
65         OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
66     }
67 
68     /// <summary>
69     /// Raises this object's PropertyChanged event.
70     /// </summary>
71     /// <param name="args">The PropertyChangedEventArgs</param>
72     protected virtual void OnPropertyChanged(PropertyChangedEventArgs args)
73     {
74         PropertyChanged?.Invoke(this, args);
75     }
76 }

 

posted @ 2025-12-19 15:07  家煜宝宝  阅读(0)  评论(0)    收藏  举报