代码之家  ›  专栏  ›  技术社区  ›  Nathan Ernst

具有多个(失败的)ValidationRules的BindingGroup

  •  1
  • Nathan Ernst  · 技术社区  · 15 年前

    我今天在工作中遇到了一个问题 BindingGroup 有多个 ValidationRule 同时发生故障的。问题是,我有一个 ArgumentException 从沸腾中冒出来 BindingGroup.ValidateWithoutUpdate 当我尝试确定是否有任何错误时(即设置 CanExecute 一个命令 false ).

    我已经成功地将其提取到以下示例中(抱歉,它仍然跨越多个源,但我已经将所有相关部分都包含在一个新的WPF项目中,这些部分应该是可以复制/粘贴的):

    <Window 
        x:Class="BindingGroupTest.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:l="clr-namespace:BindingGroupTest"
        xmlns:diag="clr-namespace:System.Diagnostics;assembly=WindowsBase"
        Title="Window1" Height="300" Width="300">
    
        <Window.BindingGroup>
            <BindingGroup Name="RootBindingGroup">
                <BindingGroup.ValidationRules>
                    <l:TestRule1 />
                    <l:TestRule2 />
                </BindingGroup.ValidationRules>
            </BindingGroup>
        </Window.BindingGroup>
    
        <StackPanel>
            <TextBox Text="{Binding 
                Path=Name, 
                BindingGroupName=RootBindingGroup,
                UpdateSourceTrigger=PropertyChanged,
                diag:PresentationTraceSources.TraceLevel=High}" />
            <TextBox Text="{Binding 
                Path=Age, 
                BindingGroupName=RootBindingGroup,
                UpdateSourceTrigger=PropertyChanged,
                diag:PresentationTraceSources.TraceLevel=High}" />
            <Button Content="Validate" Click="DoValidate" />
        </StackPanel>
    </Window>
    

    Window1.xaml.cs:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    
    namespace BindingGroupTest
    {
        /// <summary>
        /// Interaction logic for Window1.xaml
        /// </summary>
        public partial class Window1 : Window
        {
            public Window1()
            {
                this.DataContext = new Person()
                {
                    Name="Test",
                    Age=30,
                };
    
                InitializeComponent();
    
                this.BindingGroup.BeginEdit();
            }
    
            private void DoValidate(object sender, RoutedEventArgs e)
            {
                try
                {
                    if (!this.BindingGroup.ValidateWithoutUpdate())
                        MessageBox.Show("Validation failed!");
                    else
                        MessageBox.Show("Validation passed!");
                }
                catch (Exception ex)
                {
                    var msg = "While validating, caught exception: " + ex.Message;
                    MessageBox.Show(msg);
                }
            }
        }
    }
    

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace BindingGroupTest
    {
        public class Person
        {
            public string Name { get; set; }
            public int Age { get; set; }
        }
    }
    

    测试规则1.cs:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    
    namespace BindingGroupTest
    {
        public class TestRule1 : ValidationRule
        {
            public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo)
            {
                var p = ((BindingGroup)value).Items[0] as Person;
                if (p == null)
                    return ValidationResult.ValidResult;
    
                if (p.Age < 0)
                    return new ValidationResult(false, "Surely, you've been born yet!");
    
                return ValidationResult.ValidResult;
            }
        }
    }
    

    测试规则2.cs:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    
    namespace BindingGroupTest
    {
        public class TestRule2 : ValidationRule
        {
            public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo)
            {
                var p = ((BindingGroup)value).Items[0] as Person;
                if (p == null)
                    return ValidationResult.ValidResult;
    
                if (string.IsNullOrEmpty(p.Name))
                    return new ValidationResult(false, "What, no name?");
    
                return ValidationResult.ValidResult;
            }
        }
    }
    

    基本上,我的问题是如果两者 TestRule1 fail, I get an 参数异常 bubbling up when I call with message "Cannot have duplicates in this Collection", parameter name: "validationError". I dug around through the implementation of 绑定组 , and it seems that it is using itself as the second parameter to 验证错误 , which is the 绑定错误 parameter, which the underlying

    对同一业务对象的不同属性进行操作的,将这些属性折叠为一个单独的属性是没有意义的 ). 另外,我能找到的每一个使用 绑定组 验证规则

    是我做错了什么,还是这看起来像是一个错误 绑定组 实现,就像我现在想的那样。

    1 回复  |  直到 15 年前
        1
  •  2
  •   Quartermeister    15 年前

    如果您在.NET4.0中运行它,它将按您所期望的方式工作,因此看起来它确实是一个bug,并已在下一版本中修复。