好的,这就是问题所在:我编写了一个UserControl,它接收一个新的值,比如每100毫秒,并用它做一些事情。它必须处理每个新的值设置器,即使值没有改变。 UserControl有几个DependencyProperties:
public double CurrentValue
{
get { return (double)GetValue(CurrentValueProperty); }
set { SetValue(CurrentValueProperty, value); }
}
public static readonly DependencyProperty CurrentValueProperty =
DependencyProperty.Register("CurrentValue", typeof(double), typeof(GraphControl), new UIPropertyMetadata(0d));
在使用此控件的XAML中,我只是将CurrentValue的Binding
设置为(启用了INotifyPropertyChanged)属性:
<uc:UserControl CurrentValue="{Binding MyValue}" ... />
视图模型:
public double MyValue
{
get { return _value; }
set
{
//if (_value == value) return;
_value= value;
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs("MyValue"));
}
}
正如您所看到的,我明确地注释掉了if equals then return
,因此即使值更新为相同的值,它也会触发PropertyChanged事件。
现在回到我的用户控件,我尝试以两种方式注册ValueChanged;首先使用DependencyPropertyDescriptor
:
var propertyDescriptor = DependencyPropertyDescriptor.FromProperty(CurrentValueProperty, typeof(GraphControl));
propertyDescriptor.AddValueChanged(this, OnCurrentValueChanged);
或使用UIPropertyMetaData
:
new UIPropertyMetadata(0d, OnCurrentValueChangedCallback)
所以回调的存根看起来像:
private void Callback(object sender, EventArgs e){
//do stuff
}
现在问题是,当值没有明确更改时,不会触发回调。我检查过,PropertyChanged
事件在我的viewmodel中触发,但控件没有看到更改。当值更改为新值时,它将按预期处理回调
有没有办法覆盖这种行为,以便我的回调方法总是被击中?
修改
我也尝试使用CoerceValueCallback
,并且当值保持不变时,它会被击中,但是我认为这对我的问题没有帮助...
答案 0 :(得分:5)
您可以将值包装在对象中,即创建一个类来保存它 - 然后每次都将属性设置为包含新值的该类的新实例。这意味着你每秒创建~10个对象,但它们各不相同,会触发更改事件,并且只是很小(无论如何都是GC'd)。 :)
答案 1 :(得分:0)
另一种方法是暂时将值切换为其他值,然后恢复前一个值。您可以在Coerce回调中透明地完成整个技巧:
public static readonly DependencyProperty TestProperty = DependencyProperty.Register(
"Test", typeof(object), typeof(School),
new PropertyMetadata(null, TestChangedCallback, TestCoerceCallback));
static object TestCoerceCallback(DependencyObject d, object baseValue)
{
if (baseValue != null && (d.GetValue(TestProperty) == baseValue))
{
d.SetCurrentValue(TestProperty, null);
d.SetCurrentValue(TestProperty, baseValue);
}
return baseValue;
}
只需确保您的属性代码可以正常处理null
值。