如何使装订方面的DependencyProperty值胁迫?
-
21-08-2019 - |
题
我有与CoerceValueCallback一个DependencyProperty的控制。 此属性绑定到模型对象上的属性。
当设置控制属性到导致胁迫绑定推的不受胁迫强>值,以模型对象的值。在控制的特性值被正确地强制。
我如何绑定到强制价值推到模型对象?
void Initialize()
{
UIObject ui = new UIObject();
ModelObject m = new ModelObject();
m.P = 4;
Binding b = new Binding("P");
b.Source = m;
b.Mode = BindingMode.TwoWay;
Debug.WriteLine("SetBinding");
// setting the binding will push the model value to the UI
ui.SetBinding(UIObject.PProperty, b);
// Setting the UI value will result in coercion but only in the UI.
// The value pushed to the model through the binding is not coerced.
Debug.WriteLine("Set to -4");
ui.P = -4;
Debug.Assert(ui.P == 0);
// The binding is TwoWay, the DP value is coerced to 0.
Debug.Assert(m.P == 0); // Not true. This will be -4. Why???
}
class UIObject : FrameworkElement
{
public static readonly DependencyProperty PProperty =
DependencyProperty.Register("P", typeof(int), typeof(UIObject),
new FrameworkPropertyMetadata(
new PropertyChangedCallback(OnPChanged),
new CoerceValueCallback(CoerceP)));
public int P
{
get { return (int)GetValue(PProperty); }
set { SetValue(PProperty, value); }
}
private static void OnPChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
Debug.WriteLine(typeof(UIObject) + ".P changed from " + e.OldValue + " to " + e.NewValue);
}
private static object CoerceP(DependencyObject sender, object value)
{
int p = (int)value;
if (p < 0)
{
Debug.WriteLine(typeof(UIObject) + ".P coerced from " + p + " to 0");
p = 0;
}
return p;
}
}
class ModelObject
{
private int p;
public int P
{
get
{
Debug.WriteLine(this + ".P returned " + this.p);
return this.p;
}
set
{
Debug.WriteLine(this + ".P changed from +" + this.p + " to " + value);
this.p = value;
}
}
}
解决方案
我不认为要挟回调意味着是一个双行道。一个解决方法是,以更新裹胁回调的内部模型的值。
其他提示
我认为,这就是胁迫的整体思路 - 在飞行正确的值,而不会触发任何其他相关性的修改。可以使用下面的代码,而不是天然的强制机制:
OnPChanged(/* ... */)
{
// ...
var coercedP = CoerceP(P);
if (P != coercedP)
P = coercedP;
// ...
}
HTH。
这里是您的目标对象上设置的值的扩展方法
public static void SetTargetValue<T>(this FrameworkElement element, DependencyProperty dp, T value)
{
var binding = BindingOperations.GetBinding(element, dp);
if (binding == null) return;
var name = binding.Path.Path;
var splits = name.Split('.');
var target = element.DataContext;
for (var i = 0; i < splits.Length; i++)
{
PropertyInfo property;
if (i == splits.Length - 1)
{
property = target.GetType().GetProperty(splits[i]);
property.SetValue(target, value);
}
else
{
property = target.GetType().GetProperty(splits[i]);
target = property.GetValue(target);
}
}
}
因此,在该方法中,使用结合,可以设置值到来源。五言源路径可以有很多名字 - Property1.Property2.Property3等。 在要挟的方法,你只需要调用此方法:
private static object CoerceProperty(DependencyObject d, object baseValue)
{
if (!Check)
{
var sender = (FrameworkElement)d;
sender.SetTargetValue(MyPropertyProperty, myValue);
return needValue;
}
return baseValue;
}
不隶属于 StackOverflow