1

私は今日仕事で問題に遭遇しました。そこでは、同時に失敗しBindingGroupている複数のがあります。ValidationRule問題は、エラーがあるかどうかを判断しようとすると(つまり、コマンドのをに設定するために) ArgumentException、withingからバブリングが発生することです。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);
            }
        }
    }
}

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

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

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

基本的に、私の問題は、TestRule1TestRule2 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 toValidationErrorbindingInErrorValidationErrorCollection`, which is theの両方parameter, which the underlyingが一意である必要がある場合です。

確かに、この例は考案されたものですが、そうではない私の現実の問題を完全に示しています。(私には2つの完全に独立したValidationRule、同じビジネスオブジェクトの異なる属性を操作しているものがあり、これらを1つにまとめても意味がありませんValidationRule)。さらに、私が見つけることができるすべての例BindingGroupは、単一の使用を示していますValidationRuleが、構造は、一度に1つだけが失敗する限り、明らかに複数のルールをサポートし、受け入れます。

私は何か間違ったことをしているのでしょうか、それともBindingGroup私が現在考えているように、これは実装のバグのように見えますか?

その価値については、.Net3.5SP1でVS2008を使用しています。

4

1 に答える 1

2

.NET 4.0で実行すると期待どおりに機能するため、実際にはバグであり、次のリリースで修正されているようです。

于 2010-07-20T02:47:35.860 に答える