如何使 Binding 尊重 DependencyProperty 值强制?
我有一个带有 DependencyProperty 和 CoerceValueCallback 的控件。 该属性绑定到模型对象上的属性。
当将控件属性设置为导致强制的值时,绑定会将非强制值推送到模型对象。 控件上的属性值已正确强制。
如何获取 Binding 将强制值推送到模型对象?
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;
}
}
}
I have a control with a DependencyProperty with a CoerceValueCallback.
This property is bound to a property on a model object.
When setting the control property to a value that causes coercion the Binding pushes the uncoerced value to the model object. The property value on the control is coerced correctly.
How do I get the Binding to push the coerced value to the model object?
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;
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我认为这就是强制的整个想法 - 即时正确的值而不触发任何其他依赖项的修改。 您可以使用下面的代码代替本机强制机制:
HTH。
I think that that's the whole idea of the coercion - correct value on the fly without triggering modification of any other dependencies. You can use the code below instead of native coercion mechanisms:
HTH.
我不认为强制回调是双向的。 一种解决方法是在强制回调内更新模型的值。
I don't think the coerce callback is meant to be a two-way street. One workaround would be to update the model's value inside of the coerce callback.
这是扩展方法,您可以在目标对象上设置值
因此,在此方法中,使用绑定,您可以将值设置为源。 当然,源路径可以有很多名称 - Property1.Property2.Property3 等。
在强制方法中你只需要调用这个方法:
Here is extension method where you set value on target object
So, in this method, using binding, you can set value to source. Of cource source Path can have a lot of names - Property1.Property2.Property3 and etc.
In coerce method you need only call this method: