简体   繁体   English

调用绑定的ViewModel OnPropertyChanged但值相同时,获取IDataErrorInfo验证以在子UserControl中更新

[英]Getting IDataErrorInfo validation to update in child UserControl when bound ViewModel OnPropertyChanged is called but the value is the same

I have a reusable UserControl defined that will be used multiple times within the parent form, to represent different instances of a configured object. 我定义了一个可重用的UserControl,它将在父窗体中多次使用,以表示已配置对象的不同实例。 This UserControl has several TextBoxes representing configurable properties. 此UserControl有几个表示可配置属性的TextBox。 For one of these properties, the value must be unique across all instances of the reusable UserControl. 对于这些属性之一,该值在可重复使用的UserControl的所有实例中必须是唯一的。

My parent form utilizes these usercontrols like this: 我的父表单利用了以下这些用户控件:

<namespace:ReusableControl
  Property1="{Binding Path=ViewModelProperty1a, Mode=TwoWay}"
  Property2="{Binding Path=ViewModelProperty2a, Mode=TwoWay}"
  UniqueProperty="{Binding Path=VMUniquePropertya, Mode=TwoWay}"/>

<namespace:ReusableControl
  Property1="{Binding Path=ViewModelProperty1b, Mode=TwoWay}"
  Property2="{Binding Path=ViewModelProperty2b, Mode=TwoWay}"
  UniqueProperty="{Binding Path=VMUniquePropertyb, Mode=TwoWay}"/>
And the UserControl property looks like this: 并且UserControl属性如下所示:
public string this[string columnName]
{
    get
    {
        string error = string.Empty;
        switch (columnName)
        {
        case nameof(UniqueProperty):
            if (!((MyViewModel)DataContext).UniquePropertiesAreUnique())
            {
                error = "not unique";
            }
            break;
        //Other cases here, omitted from example
        }
        return error;
    }
}

//-------------------------------
//Just to show the codebehind for the property:
public string UniqueProperty
        {
            get { return (string)GetValue(UniquePropertyDP); }
            set { SetValue(UniquePropertyDP, value); }
        }

        public static readonly DependencyProperty UniquePropertyDP=
            DependencyProperty.Register(
                "UniqueProperty",
                typeof(string),
                typeof(ReusableControl),
                new PropertyMetadata(string.Empty));

The codebehind for the UserControl contains IDataErrorInfo validation: UserControl的背后代码包含IDataErrorInfo验证:

//In the setter for VMUniquePropertyb:
var temp = VMUniquePropertya;
VMUniquePropertya = null;
VMUniquePropertya = temp;

Everything appears to be wired up and bound correctly; 一切似乎都已正确连接并绑定; the values update when the UI is changed as desired. 根据需要更改UI时,值将更新。 If I change one of the unique property values such that it is no longer unique, I get the red border around that text box, but this is where the issue comes in - the red border only appears around the text box I just changed, not both of the instances of UniqueProperty. 如果更改唯一属性值之一以使其不再唯一,则会在该文本框周围出现红色边框,但这就是问题所在-红色边框仅出现在我刚刚更改的文本框周围,而不是这两个UniqueProperty实例。 In the ViewModel, when either of the UniqueProperty values are changed, it triggers OnPropertyChanged for the other, but this still isn't causing the validation border to appear. 在ViewModel中,当其中一个UniqueProperty值更改时,它将触发另一个的OnPropertyChanged,但这仍然不会导致显示验证边框。 If I replace OnPropertyChange with an explicit call to update the value ie: 如果我用显式调用替换OnPropertyChange来更新值,即:

 //In the setter for VMUniquePropertyb: var temp = VMUniquePropertya; VMUniquePropertya = null; VMUniquePropertya = temp; 
Then I do get the validation border to appear on both text boxes when that value is changed to match the other, and both borders disappear when either value is changed to be unique again. 然后,当该值更改为与另一个匹配时,我确实使验证边框同时出现在两个文本框中,并且当其中一个值再次更改为唯一时,两个边框都消失了。 Of course, this is a hack, and also will cause an infinite loop if used on both properties. 当然,这是一个hack,如果同时在两个属性上使用,也会导致无限循环。 How can I accomplish the same result with OnPropertyChanged? 如何使用OnPropertyChanged完成相同的结果?

I found a solution that works for me. 我找到了适合我的解决方案。 There may be better ways to do this, but this works fairly well. 也许有更好的方法可以做到这一点,但是效果很好。

By using the CoerceValueCallback on the DependencyProperty, we can execute code whenever the value of the property is re-evaluated, not just when it actually changes. 通过在CoerceValueCallback上使用CoerceValueCallback ,我们可以在重新评估属性值时执行代码,而不仅仅是在其实际更改时执行代码。 This will fire when the PropertyChange event occurs in the ViewModel because the binding is re-evaluated. 当ViewModel中发生PropertyChange事件时,将触发此事件,因为重新评估了绑定。 This looks like this: 看起来像这样:

public string UniqueProperty
        {
            get { return (string)GetValue(UniquePropertyDP); }
            set { SetValue(UniquePropertyDP, value); }
        }

public static readonly DependencyProperty UniquePropertyDP=
    DependencyProperty.Register(
        "UniqueProperty",
        typeof(string),
        typeof(ReusableControl),
        new PropertyMetadata(string.Empty, null, UniquePropertyCoerceValueCallback));

private static object UniquePropertyCoerceValueCallback(DependencyObject d, object value)
{
    ((ReusableControl)d).UniquePropertyTextBox.GetBindingExpression(TextBox.TextProperty)
        .UpdateTarget();

    return value;
}
When the value of one of the unique properties changes and the ViewModel fires the PropertyChange event for the other unique property in the ViewModel, the DependencyProperty in the UserControl will be re-coerced, triggering this callback and updating validation. 当唯一属性之一的值更改并且ViewModel触发ViewModel中另一个唯一属性的PropertyChange事件时,将重新强制UserControl中的DependencyProperty,触发此回调并更新验证。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何使用IDataErrorInfo强制验证错误更新ViewModel中的View? - How to force validation errors update on View from ViewModel using IDataErrorInfo? 将值从绑定的ViewModel传递到UserControl - Passing value from bound ViewModel to UserControl 如何将实现IDataErrorInfo的视图模型绑定到UserControl并传播验证错误? - How do you bind a viewmodel which implements IDataErrorInfo to a UserControl and propagate the validation errors? 我的UserControl中的DependencyProperty无法更新ViewModel中的绑定属性 - DependencyProperty in my UserControl fails to update bound property in ViewModel 在ViewModel实体上使用DataAnnotation进行Prism IDataErrorInfo验证 - Prism IDataErrorInfo validation with DataAnnotation on ViewModel Entities 触发OnPropertyChanged时绑定的文本框/标签未更新 - Bound Textbox/Labels not updating when OnPropertyChanged fired IDataErrorInfo绑定到子项时不起作用 - IDataErrorInfo not working when binding to child 传递给UserControl的继承的ViewModel被视为子ViewModel - Inherited ViewModel passed to UserControl is treated as child ViewModel IDataErrorInfo具有对所有文本框相同的验证 - IDataErrorInfo with the same validation for all the text boxes 值转换后的WPF IDataErrorInfo验证 - WPF IDataErrorInfo validation after Value Conversion
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM