在WPF中绑定数据时进行验证
我已经用WPF(MVVM)构建了一个应用程序,并添加了验证。以下是我的结果: 您会注意到输入文本框周围的红色斜纹。问题是,我不想在启动表单时让客户端面对验证错误。输入数据或按Submit键时最好 在SO上有一些类似的问题,但尚未找到合适的解决方案。 (初始化时重置每个控件不是解决方案) 所以问题是如何启动表单和: 选项A:(轻松)重置验证 选项B:在绑定之后才调用验证 选项C:其他不错的解决方案 下载代码:在WPF中绑定数据时进行验证,wpf,validation,mvvm,Wpf,Validation,Mvvm,我已经用WPF(MVVM)构建了一个应用程序,并添加了验证。以下是我的结果: 您会注意到输入文本框周围的红色斜纹。问题是,我不想在启动表单时让客户端面对验证错误。输入数据或按Submit键时最好 在SO上有一些类似的问题,但尚未找到合适的解决方案。 (初始化时重置每个控件不是解决方案) 所以问题是如何启动表单和: 选项A:(轻松)重置验证 选项B:在绑定之后才调用验证 选项C:其他不错的解决方案 下载代码: <Window x:Class="Validation.MainWindow"
<Window x:Class="Validation.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="150" Width="250">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto"></RowDefinition>
<RowDefinition Height="auto"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="80"></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<!-- Name -->
<Label Grid.Column="0" Grid.Row="0">Name</Label>
<TextBox Grid.Column="1" Grid.Row="0"
Text="{Binding Model.Name, UpdateSourceTrigger=PropertyChanged,ValidatesOnDataErrors=True}"></TextBox>
<!-- Age -->
<Label Grid.Column="0" Grid.Row="1">Age</Label>
<TextBox Grid.Column="1" Grid.Row="1"
Text="{Binding Model.Age, UpdateSourceTrigger=PropertyChanged,ValidatesOnDataErrors=True}"></TextBox>
<!-- Submit/Cancel -->
<StackPanel Grid.Column="1" Grid.Row="2" FlowDirection="LeftToRight">
<Button>Cancel</Button>
<Button>Submit</Button>
</StackPanel>
</Grid>
</Window>
public class FormViewModel
{
#region constructors
public FormViewModel()
{
Model = new FormModel();
}
#endregion
#region properties
public FormModel Model { get; set; }
#endregion
}
public class FormModel : INotifyPropertyChanged, IDataErrorInfo
{
#region notifypropertychanged
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = this.PropertyChanged;
if (handler != null)
{
var e = new PropertyChangedEventArgs(propertyName);
handler(this, e);
}
}
#endregion
#region dataerrorinfo
public string Error
{
get { return null; }
}
public string this[string columnName]
{
get
{
switch (columnName)
{
case "Name":
if (string.IsNullOrEmpty(Name))
{
return "Name is required";
}
break;
case "Age":
if (Age < 18 || Age > 50)
{
return "Are you kidding?";
}
break;
}
return null;
}
}
#endregion
#region properties
private string name;
public string Name { get { return name; } set { name = value; OnPropertyChanged("Name"); } }
private int age;
public int Age { get { return age; } set { age = value; OnPropertyChanged("Age"); } }
#endregion
}
查看代码:
<Window x:Class="Validation.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="150" Width="250">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto"></RowDefinition>
<RowDefinition Height="auto"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="80"></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<!-- Name -->
<Label Grid.Column="0" Grid.Row="0">Name</Label>
<TextBox Grid.Column="1" Grid.Row="0"
Text="{Binding Model.Name, UpdateSourceTrigger=PropertyChanged,ValidatesOnDataErrors=True}"></TextBox>
<!-- Age -->
<Label Grid.Column="0" Grid.Row="1">Age</Label>
<TextBox Grid.Column="1" Grid.Row="1"
Text="{Binding Model.Age, UpdateSourceTrigger=PropertyChanged,ValidatesOnDataErrors=True}"></TextBox>
<!-- Submit/Cancel -->
<StackPanel Grid.Column="1" Grid.Row="2" FlowDirection="LeftToRight">
<Button>Cancel</Button>
<Button>Submit</Button>
</StackPanel>
</Grid>
</Window>
public class FormViewModel
{
#region constructors
public FormViewModel()
{
Model = new FormModel();
}
#endregion
#region properties
public FormModel Model { get; set; }
#endregion
}
public class FormModel : INotifyPropertyChanged, IDataErrorInfo
{
#region notifypropertychanged
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = this.PropertyChanged;
if (handler != null)
{
var e = new PropertyChangedEventArgs(propertyName);
handler(this, e);
}
}
#endregion
#region dataerrorinfo
public string Error
{
get { return null; }
}
public string this[string columnName]
{
get
{
switch (columnName)
{
case "Name":
if (string.IsNullOrEmpty(Name))
{
return "Name is required";
}
break;
case "Age":
if (Age < 18 || Age > 50)
{
return "Are you kidding?";
}
break;
}
return null;
}
}
#endregion
#region properties
private string name;
public string Name { get { return name; } set { name = value; OnPropertyChanged("Name"); } }
private int age;
public int Age { get { return age; } set { age = value; OnPropertyChanged("Age"); } }
#endregion
}
型号代码:
<Window x:Class="Validation.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="150" Width="250">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto"></RowDefinition>
<RowDefinition Height="auto"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="80"></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<!-- Name -->
<Label Grid.Column="0" Grid.Row="0">Name</Label>
<TextBox Grid.Column="1" Grid.Row="0"
Text="{Binding Model.Name, UpdateSourceTrigger=PropertyChanged,ValidatesOnDataErrors=True}"></TextBox>
<!-- Age -->
<Label Grid.Column="0" Grid.Row="1">Age</Label>
<TextBox Grid.Column="1" Grid.Row="1"
Text="{Binding Model.Age, UpdateSourceTrigger=PropertyChanged,ValidatesOnDataErrors=True}"></TextBox>
<!-- Submit/Cancel -->
<StackPanel Grid.Column="1" Grid.Row="2" FlowDirection="LeftToRight">
<Button>Cancel</Button>
<Button>Submit</Button>
</StackPanel>
</Grid>
</Window>
public class FormViewModel
{
#region constructors
public FormViewModel()
{
Model = new FormModel();
}
#endregion
#region properties
public FormModel Model { get; set; }
#endregion
}
public class FormModel : INotifyPropertyChanged, IDataErrorInfo
{
#region notifypropertychanged
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = this.PropertyChanged;
if (handler != null)
{
var e = new PropertyChangedEventArgs(propertyName);
handler(this, e);
}
}
#endregion
#region dataerrorinfo
public string Error
{
get { return null; }
}
public string this[string columnName]
{
get
{
switch (columnName)
{
case "Name":
if (string.IsNullOrEmpty(Name))
{
return "Name is required";
}
break;
case "Age":
if (Age < 18 || Age > 50)
{
return "Are you kidding?";
}
break;
}
return null;
}
}
#endregion
#region properties
private string name;
public string Name { get { return name; } set { name = value; OnPropertyChanged("Name"); } }
private int age;
public int Age { get { return age; } set { age = value; OnPropertyChanged("Age"); } }
#endregion
}
公共类FormModel:INotifyPropertyChanged,IDataErrorInfo
{
#区域notifypropertychanged
公共事件属性更改事件处理程序属性更改;
受保护的虚拟void OnPropertyChanged(字符串propertyName)
{
PropertyChangedEventHandler处理程序=this.PropertyChanged;
if(处理程序!=null)
{
var e=新的PropertyChangedEventArgs(propertyName);
处理者(本,e);
}
}
#端区
#区域数据错误信息
公共字符串错误
{
获取{return null;}
}
公共字符串此[string columnName]
{
得到
{
开关(列名称)
{
案例“名称”:
if(string.IsNullOrEmpty(Name))
{
返回“名称为必填项”;
}
打破
案例“年龄”:
如果(年龄<18岁| |年龄>50岁)
{
return“你在开玩笑吗?”;
}
打破
}
返回null;
}
}
#端区
#区域属性
私有字符串名称;
公共字符串名称{get{return Name;}set{Name=value;OnPropertyChanged(“Name”);}
私人互联网;
public int Age{get{return Age;}set{Age=value;OnPropertyChanged(“Age”);}
#端区
}
解决方案(目前)
?
*
几天前我回答了一个类似的问题:
首先,如果您的规则规定first和lastname不应为空-
用户有权看到验证错误
我所做的是对空/初始值使用ValidationTemplate,所以
用户只看到一个“*”作为必填字段
是完整的答案我很喜欢你的方法,我会尝试一下。尝试一下,并将结果添加到问题中。