UserControl中Dependency Property绑定的FrameRate属性更新不生效问题
问题分析与解决方案
你的问题核心在于WPF绑定需要属性变化通知才能自动更新UI,而当前的FrameRate属性既不是依赖属性,也没有实现INotifyPropertyChanged接口的通知机制,所以即使m_frameRate.Current的值更新了,UI也无法感知到变化。
具体修复步骤:
1. 让UiView实现INotifyPropertyChanged接口
这是WPF中CLR属性通知UI更新的标准方式,先给UiView添加接口实现:
public class UiView : INotifyPropertyChanged { // 实现PropertyChanged事件 public event PropertyChangedEventHandler PropertyChanged; // 封装触发事件的方法 protected virtual void OnPropertyChanged(string propertyName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } private readonly FrameRate m_frameRate = new FrameRate(); public double FrameRate => m_frameRate.Current; public UiView() { // 监听FrameRate实例中Current属性的变化,触发自身的PropertyChanged事件 m_frameRate.CurrentChanged += (s, e) => OnPropertyChanged(nameof(FrameRate)); } }
2. 给FrameRate类添加属性变化通知
因为FrameRate的Current属性更新时,需要通知UiView,所以我们要给FrameRate的Current属性添加事件通知:
public class FrameRate { private double _current; public double Current { get => _current; set { if (_current != value) { _current = value; // 触发属性变化事件 OnCurrentChanged(); } } } // 定义Current属性变化的事件 public event EventHandler CurrentChanged; private void OnCurrentChanged() { CurrentChanged?.Invoke(this, EventArgs.Empty); } }
为什么这样能解决问题?
- 当
FrameRate.Current更新时,会触发CurrentChanged事件; UiView监听这个事件,在事件触发时调用OnPropertyChanged(nameof(FrameRate)),告诉WPF绑定系统FrameRate属性已经变化;- WPF绑定系统收到通知后,会重新读取
FrameRate的值并更新TextBlock的内容。
备选方案:把FrameRate改成依赖属性
如果你不想用INotifyPropertyChanged,也可以把UiView中的FrameRate定义为依赖属性,但这种方式对于只读属性来说不如INotifyPropertyChanged灵活,示例如下:
public class UiView : DependencyObject { private readonly FrameRate m_frameRate = new FrameRate(); public static readonly DependencyProperty FrameRateProperty = DependencyProperty.Register(nameof(FrameRate), typeof(double), typeof(UiView)); public double FrameRate { get => (double)GetValue(FrameRateProperty); private set => SetValue(FrameRateProperty, value); } public UiView() { m_frameRate.CurrentChanged += (s, e) => FrameRate = m_frameRate.Current; } }
不过更推荐第一种INotifyPropertyChanged的方案,因为它更符合WPF中普通业务类的设计习惯。
内容的提问来源于stack exchange,提问作者Vahid
相关产品推荐
相关产品推荐

