在我的应用程序中,我有绑定到TextBoxes的数字(double或int)ViewModel属性.ViewModel实现IDataErrorInfo以检查输入的值是否落在"业务逻辑"的可接受范围内(例如,高度不能为负值).我每页都有一些TextBox,并且有一个按钮(在向导中称为"next"),启用属性绑定到ViewModel布尔值,该布尔值指定整个页面上是否有任何错误.根据我编写的IDataErrorInfo规则,使用有效/无效值正确更新按钮的启用/禁用状态.
但是,由于输入值没有转换(即"12bd39"不是有效的双精度),因此无法让我的viewmodel知道何时抛出异常,因此在转换异常的情况下我的'next'按钮尽管输入错误,仍会保持启用 然而,由于我的绑定,GUI正确地反映了装饰者的错误:
<TextBox Text="{Binding Temperature, Mode=TwoWay, ValidatesOnExceptions=True, ValidatesOnDataErrors=True, UpdateSourceTrigger=PropertyChanged}"/>
Run Code Online (Sandbox Code Playgroud)
如何让视图知道发生了'ValidatesOnExceptions'样式错误.Josh Smith在这里的看法似乎依赖于使每个ViewModel属性成为一个字符串并滚动自己的异常检查,这似乎是很多额外的工作.我还开始寻找卡尔Shifflett的实现在这里,但我似乎无法捕捉到的路由事件把这个代码到视图的代码隐藏文件时,我会想到:
public ViewClass()
{
this.InitializeComponent();
this.AddHandler(System.Windows.Controls.Validation.ErrorEvent, new RoutedEventHandler(ValidationErrorHandler));
}
private void ValidationErrorHandler(object sender, RoutedEventArgs e)
{
var blah = e as System.Windows.Controls.ValidationErrorEventArgs;
if (blah.Action == ValidationErrorEventAction.Added)
{
}
else if (blah.Action == ValidationErrorEventAction.Removed)
{
}
}
Run Code Online (Sandbox Code Playgroud)
Silverlight似乎也有一个你可以订阅的事件,但我找不到WPF(3.5)中的确切等价物.任何帮助表示赞赏!
开始使用所有这些MVVM的东西,我正在关注Josh Smith的这篇文章,该文章讨论了使用MVVM时的验证方法.这个例子很简单,我开始想知道如何在我自己的应用程序中使用它.
在我的BLL中,我有一个BookInfo实现IDataErrorInfo 的类来报告无效值,例如"发布日期不能在将来"或"页数不能为负".然后我AddBookViewModel会检查新创建的状态BookInfo,看看是否存在错误,并且AddBookView将在相应的TextBox旁边显示一个红色blob.那些东西很简单,就像帖子中的例子一样.
现在我的BookInfo班级还有一个作者ID列表.在我的数据库中添加新的BookInfo后,我需要检查这些作者ID是否已经存在.
这个检查应该在我的BookInfo课上完成吗?如果是这样,那么我必须将我的BLL AuthorManager对象传递给BookInfo构造函数,因为前者将包含诸如的方法CheckIfExists(int authorID).
这是推荐的方法吗?如果DB中有很多记录怎么办?动态检查会影响性能吗?
另一方面,在BookInfo课堂上和其他地方执行一些检查似乎有点混乱......特别是当所有这些检查都可以分类到同一组时...即.确保新创建的BookInfo对象有效.或者也许我错了,因为我没有经验来做出正确的判断.
一些指导?
我正在编写一个WPF应用程序,我想使用Data Annotations来指定诸如RequiredFields Range等的内容.
我的ViewModel类使用常规INotifyPropertyChanged接口,我可以使用C#4轻松地验证整个对象Validator,但如果它们没有正确验证,我还希望这些字段突出显示为红色.我在这里找到了这篇博文(http://blogs.microsoft.co.il/blogs/tomershamam/archive/2010/10/28/wpf-data-validation-using-net-data-annotations-part-ii.aspx )讨论如何编写基本视图模型来实现IDataErrorInfo并简单地使用Validator,但实现实际上并没有编译,也无法看到它是如何工作的.有问题的方法是这样的:
/// <summary>
/// Validates current instance properties using Data Annotations.
/// </summary>
/// <param name="propertyName">This instance property to validate.</param>
/// <returns>Relevant error string on validation failure or <see cref="System.String.Empty"/> on validation success.</returns>
protected virtual string OnValidate(string propertyName)
{
if (string.IsNullOrEmpty(propertyName))
{
throw new ArgumentException("Invalid property name", propertyName);
}
string error = string.Empty;
var value = GetValue(propertyName);
var results = new List<ValidationResult>(1);
var result = Validator.TryValidateProperty(
value, …Run Code Online (Sandbox Code Playgroud) 我搜索并没有看到解决方案.
如果我没有在组合框tooltip属性中设置工具提示,我只能获得验证以显示工具提示.我希望看到验证错误工具提示,否则显示组合框属性中的工具提示.当我从tooltip属性中删除文本时(即从组合框的属性面板中),验证工具提示显示正常.
Application.Resources(App.XAML)中的XAML用于显示验证错误的工具提示
<Style x:Key="StandardComboBoxStyle" TargetType="{x:Type ComboBox}">
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="True">
<Setter Property="ToolTip" Value="{Binding RelativeSource={x:Static RelativeSource.Self}, Path=(Validation.Errors)[0].ErrorContent}"/>
</Trigger>
</Style.Triggers>
</Style>
Run Code Online (Sandbox Code Playgroud)
我还使用了Combobox的验证模板,如下所示.这是在用户控件cs文件中的UserControl.Resources部分.
<ControlTemplate x:Key="comboBoxValidationTemplate">
<DockPanel Name="myDockPanel">
<Border BorderBrush="Red" BorderThickness="3">
<AdornedElementPlaceholder Name="MyAdorner" />
</Border>
<TextBlock Text="*" FontWeight="Bold" FontSize="18" Foreground="Red" DockPanel.Dock="Left" />
</DockPanel>
</ControlTemplate>
Run Code Online (Sandbox Code Playgroud)
控件本身定义如下.请注意,这里没有定义其他引用(但希望不相关 - 如果问题,请随时告诉我).
<ComboBox x:Name="ExposureTime" SelectedValuePath="Content"
Text="{Binding ExposureTime, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True, ValidatesOnExceptions=True}" IsEditable="True" Validation.ErrorTemplate="{StaticResource comboBoxValidationTemplate}"
HorizontalContentAlignment="Right" FontSize="18" Margin="136,47,462,0" Height="27" VerticalAlignment="Top" GotFocus="ComboBox_GotFocus_1" LostFocus="ComboBox_LostFocus_1" PreviewTextInput="ExposureTime_PreviewTextInput" Opacity="{Binding BackgroundOpacity, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" FontWeight="Thin" Style="{DynamicResource StandardComboBoxStyle}" SelectedValue="{Binding Mode=OneWay, ValidatesOnDataErrors=True, ValidatesOnExceptions=True}" IsTextSearchEnabled="False" ToolTip="My tooltip test.">
<ComboBoxItem …Run Code Online (Sandbox Code Playgroud) 在WPF中,有3种验证方法:
IDataErrorInfoINotifyDataErrorInfo是否可以同时使用它们的组合?对于我的需求,我想使用INotifyDataErrorInfo的灵活性来验证新规则,但是不想干扰要验证的同一对象的现有ValidationRules。
我有一个简单的地址输入应用程序,我正在尝试使用IDataErrorInfo接口,如asp.net网站上所述.
它适用于可以独立验证的项目,但是当某些项目依赖于其他项目时效果不佳.例如,验证邮政编码取决于国家/地区:
private string _PostalCode;
public string PostalCode
{
get
{
return _PostalCode;
}
set
{
switch (_Country)
{
case Countries.USA:
if (!Regex.IsMatch(value, @"^[0-9]{5}$"))
_errors.Add("PostalCode", "Invalid Zip Code");
break;
case Countries.Canada:
if (!Regex.IsMatch(value, @"^([a-z][0-9][a-z]) ?([0-9][a-z][0-9])$", RegexOptions.IgnoreCase))
_errors.Add("PostalCode", "Invalid postal Code");
break;
default:
throw new ArgumentException("Unknown Country");
}
_PostalCode = value;
}
}
Run Code Online (Sandbox Code Playgroud)
因此,您只能在设置国家/地区后验证邮政编码,但似乎无法控制该订单.
我可以使用IDataErrorInfo中的错误字符串,但这不会显示在字段旁边的Html.ValidationMessage中.
我正在创建一个WPF应用程序,它将使用IDataErrorInfo我的业务对象实现的数据验证.我一直在博客文章中使用这个演示来理解ValidatesOnDataErrors.
该演示是一个简单的应用程序,它将几个文本框绑定到Contact对象IDataErrorInfo,并ValidatesOnDataErrors=True在数据绑定中实现验证.要有效,文本框必须至少包含五个字符.
这是我的问题:在演示中,只要文本框失去焦点,就会触发验证.实际上,文本框在应用程序启动时初始化为无效状态(红色边框).我的应用程序必须推迟验证,直到用户单击"确定"按钮提交页面.那时,文本框应该被验证并且如果无效则进入错误状态.
那么,在用户单击"确定"按钮之前,如何在文本框上推迟验证?谢谢你的帮助.
我在几个网站上看到过使用ErrorTemplate样式发布一些应用程序的图像,如下所示:

你知道我在哪里可以找到它吗?
我正在使用MVVM,我想使用IDataErrorInfo来验证我的View.
我当前的实现包括嵌套对象和不同的ViewModel.例如,业务实体"客户"包含业务实体"地址".我在我的视图中直接访问Address,例如"Customer.Address".要验证Address中的更改,我必须在Address中实现IDataErrorInfo.
我在不同的Views/ViewModels中使用Customer或Address.在不同的Views/ViewModel中使用会导致不同的验证行为.因此,在实体本身中实现验证是不够的.
公开我想直接在ViewModel中更改的属性(创建直接设置/获取实体的新属性)似乎使ViewModel方式过于僵化.并且太大了.
我不能从Base Classes继承,因为一些商业实体已经从其他对象派生(事实上我无法改变).我目前看到的唯一选择是向业务实体添加ViewModel接口,并将业务实体中的this []调用转发到该ViewModel接口.
有关如何在ViewModel中验证这些嵌套对象的最佳实践吗?
编辑:另一个原因验证我没有看到Business Objects中的验证作为一个有用的想法是我需要在我的ViewModel中使用不同的Business Objects来验证View和数据条目.
我正在使用WPF项目MVVM.
使用验证错误的最佳做法是IDataErrorInfo什么?在我的模型或ViewModel中?
什么是用于实施验证的最佳模式?
PS我正在使用.NET3.5.
idataerrorinfo ×10
wpf ×8
validation ×6
c# ×5
mvvm ×4
.net-3.5 ×1
asp.net-mvc ×1
tooltip ×1
xaml ×1