1

我今天在工作中遇到了一个问题,其中我有一个同时失败的BindingGroup多个s。ValidationRule问题是,当我尝试确定是否有任何错误(即将命令ArgumentException设置为BindingGroup.ValidateWithoutUpdateCanExecutefalse

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

Window1.xaml:

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

个人.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; }
    }
}

测试规则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和 TestRule2 fail, I get anArgumentException bubbling up when I callthis.BindingGroup.ValidateWithoutUpdate() with message "Cannot have duplicates in this Collection", parameter name: "validationError". I dug around through the implementation ofBindingGroup , and it seems that it is using itself as the second parameter toValidationError , which is thebindingInError parameter, which the underlyingValidationErrorCollection` 需要是唯一的。

诚然,这个例子是人为的,但是,它完美地展示了我的现实世界问题,但事实并非如此。(我有 2 个完全独立ValidationRule的 s,它们对同一业务对象的不同属性进行操作,将它们折叠成一个 s 是零意义的ValidationRule)。此外,我能找到的每个示例BindingGroup都只演示了单个 的使用ValidationRule,但是该构造清楚地支持并接受多个规则,尽管显然,只要一次只有一个失败。

我是否做错了什么,或者这似乎是BindingGroup实现中的一个错误,正如我目前倾向于认为的那样。

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

4

1 回答 1

2

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

于 2010-07-20T02:47:35.860 回答