【发布时间】:2015-11-26 13:35:34
【问题描述】:
我的 DependencyProperty 有问题。假设您有一个更新某些 UI 元素的计时器,如果每 100 毫秒调用一次回调,这反过来又更新 UI,那么我没有问题,但是,如果计时器设置为 ~10 毫秒,例如,一些调用将得到忽略。我做了一个重现问题的小解决方案:
这是一个具有依赖属性的自定义 UIElement:
public class CustomLabel : Label
{
public float Range
{
get { return (float)GetValue(MaxRangeProperty); }
set { SetValue(MaxRangeProperty, value); }
}
public static readonly DependencyProperty MaxRangeProperty =
DependencyProperty.Register("Range", typeof(float), typeof(CustomLabel),
new PropertyMetadata(0f, RangePropertyChanged));
private static void RangePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var self = d as CustomLabel;
Debug.WriteLine("CustomLabel");
self.Content = self.Range;
}
}
这是一个 ViewModel,它触发一个计时器并更新一个属性,该属性又应该调用 CustomLabel 上的 DependencyProperty 上的回调。
public class ViewModel : INotifyPropertyChanged
{
Timer timer;
Thread t;
public ViewModel()
{
t = new Thread(() => timer = new Timer(new TimerCallback(CallBack), null, 0, 10));
t.Start();
Range = 100;
}
void CallBack(object state)
{
Range = (new Random()).Next(0, 1000);
}
private float _range;
public float Range
{
get { return _range; }
set
{
if (_range != value)
{
_range = value;
NotifyPropertyChanged();
Debug.WriteLine("ViewModel");
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
这是 CustomLabel 和 ViewModel 所在的视图:
<Window x:Class="TimerTest.MainWindow"
xmlns:local="clr-namespace:TimerTest"
Title="MainWindow">
<Grid>
<local:CustomLabel x:Name="customLabel" Range="{Binding Range}"/>
</Grid>
</Window>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
ViewModel = new ViewModel();
customLabel.DataContext = ViewModel;
}
public ViewModel ViewModel { get; set; }
}
所以,我在 DependencyProperty 的每一侧都做了一些 Debug.WriteLine() 语句,输出如下所示:
100ms 10ms
CustomLabel ViewModel
ViewModel CustomLabel
CustomLabel ViewModel
ViewModel ViewModel
CustomLabel CustomLabel
ViewModel ViewModel
CustomLabel ViewModel
ViewModel ViewModel
CustomLabel ViewModel
ViewModel CustomLabel
为什么会发生这种情况,我该怎么办? 谢谢你的时间。
【问题讨论】:
-
WPF 每 16.6 毫秒渲染一次屏幕,那么为什么要每 10 毫秒更新一次呢?
-
@GlenThomas 知道这一点很有趣 - 但是我的问题是为什么突然 DependencyProperty 没有收到事件。但是为了回答你的问题,我想尽快更新一个值。我真的不在乎 WPF 何时决定更新,但当它更新时,它必须是最新的值。
-
.net 计时器不过是精确的,您可以在给定的任何间隔上添加 30 毫秒。
-
@eranotzap 您可以在最后一个代码块中清楚地看到,计时器被调用(无论何时)但 DependencyProperty 没有相应地更新 - 这是这个问题的重点。即使计时器是 30 毫秒“太慢”,无论如何都应该调用 DependencyProperty 上的回调。
标签: c# wpf binding dependency-properties