BindingGroup与多个(失败)ValidationRules

时间:2010-07-20 00:45:42

标签: wpf binding validationrules

我今天遇到了一个问题,我的BindingGroupValidationRule个同时失败的ArgumentException个问题。问题是,当我尝试确定是否存在任何错误时(即将命令BindingGroup.ValidateWithoutUpdate设置为CanExecute),我从false开始<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> 冒泡

我已经设法将它提炼到以下示例(抱歉,它仍然跨越多个来源,但我已将所有应该复制/粘贴的相关部分包含在新的WPF项目中):

Window1.xaml:

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);
            }
        }
    }
}

Window1.xaml.cs:

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; }
    }
}

Person.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;
        }
    }
}

TestRule1.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;
        }
    }
}

TestRule2.cs:

TestRule1

基本上,我的问题是如果同时fail, I get an和TestRule2 bubbling up when I call ArgumentException with message "Cannot have duplicates in this Collection", parameter name: "validationError". I dug around through the implementation of this.BindingGroup.ValidateWithoutUpdate(), and it seems that it is using itself as the second parameter to BindingGroup , which is the ValidationError {{ 1}} bindingInError parameter, which the underlying ValidationErrorCollection`必须是唯一的。

不可否认,这个例子是人为的,然而,它完美地证明了我的现实问题。 (我有2个完全独立的ValidationRule s,它们在同一个业务对象的不同属性上运行,将这些属性折叠成单个ValidationRule是没有意义的。此外,我发现使用BindingGroup的每个示例都只演示了使用单个ValidationRule,但该构造明确支持并接受多个规则,尽管很明显,只要一个单独的失败时间。

我做错了什么,或者这似乎是BindingGroup实施中的错误,因为我现在倾向于思考。

对于它的价值,我使用VS2008和.Net 3.5 SP1。

1 个答案:

答案 0 :(得分:2)

如果你在.NET 4.0中运行它会以你期望的方式工作,所以它看起来确实是一个bug并且已经在下一个版本中得到修复。