我今天在工作中遇到了一个问题,我的一个BindingGroup有多个ValidationRule同时发生故障。问题是,当我尝试确定是否有任何错误时(例如,将命令上的CanExecute设置为false),我从BindingGroup.ValidateWithoutUpdate中得到了一个ArgumentException冒泡。
我已经成功地将其提炼为以下示例(抱歉,它仍然跨越多个来源,但我已经将应该复制/粘贴到新的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;
}
}
}测试规则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和TestRule2fail, I get anArgumentExceptionbubbling 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 thebindingInErrorparameter, which the underlyingValidationErrorCollection`都要求是唯一的。
诚然,这个例子是人为的,然而,它完美地展示了我的现实世界中不是的问题。(我有两个完全独立的ValidationRule,它们在同一个业务对象的不同属性上操作,将它们折叠到一个ValidationRule中是没有意义的)。此外,我能找到的每个使用BindingGroup的示例都只演示了单个ValidationRule的使用,但是该构造显然支持并接受多个规则,尽管很明显,只要一次只有一个失败。
是我做错了什么,还是像我目前倾向于认为的那样,这似乎是BindingGroup实现中的一个错误。
值得一提的是,我将VS2008与.Net 3.5 SP1一起使用。
发布于 2010-07-20 10:47:36
如果你在.NET 4.0中运行它,它将以你期望的方式工作,所以看起来它确实是一个错误,并在下一个版本中得到了修复。
https://stackoverflow.com/questions/3286192
复制相似问题