您好 我需要在我的应用程序中验证一些文本框。我决定使用验证规则 “DataErrorValidationRule”。这就是为什么在我的课上我实现了IDataErrorInfo接口并编写了aproperiate函数。在我的xaml代码中,我将绑定和验证规则添加到文本框
<TextBox x:Name="txtName" Grid.Column="3" Grid.Row="1" TextAlignment="Center" >
<TextBox.Text>
<Binding Path="Name" >
<Binding.ValidationRules>
<DataErrorValidationRule></DataErrorValidationRule>
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
验证此文本框是否正常 - 我的意思是如果数据错误,则会在文本框中显示红框。然而,我需要做的是在该文本框上显示工具提示,但更重要的是,如果任何文本框有错误的数据,我必须禁用“运行”按钮。什么是最好的方法?
EDIT 第一个问题解决了,但我有另一个问题。我需要使用MultiBindings来验证我的Button。所以我做了那样的
<Button x:Name="btnArrange" Grid.Column="0" Content="Rozmieść" Click="btnArrange_Click" >
<Button.Style>
<Style TargetType="Button">
<Style.Triggers>
<DataTrigger Value="False">
<DataTrigger.Binding>
<MultiBinding Converter="{StaticResource BindingConverter}">
<Binding ElementName="txtName" Path="Validation.HasError" />
<Binding ElementName="txtSurname" Path="Validation.HasError"/>
<Binding ElementName="txtAddress" Path="Validation.HasError"/>
</MultiBinding>
</DataTrigger.Binding>
<Setter Property="IsEnabled" Value="False"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
我的转换器看起来像那样
public class Converters : IMultiValueConverter
{
#region IMultiValueConverter Members
public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if(values !=null && values.Length > 0)
{
if (values.Cast<type>().Count(val => val) > 0)
return false;
return true;
}
return false;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
{
return null;
}
#endregion
}
但是我在这个转换器中遇到invalidCastException。在这种情况下,什么是适当的演员?我觉得好像HasError是一个bool类型所以我应该转向bool。
答案 0 :(得分:16)
要在工具提示中显示错误消息,请将其放入Application.Resources:
<Style x:Key="textBoxInError" TargetType="{x:Type TextBox}">
<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>
(来自http://msdn.microsoft.com/en-us/library/system.windows.controls.validation.errortemplate.aspx的例子)
要启用/禁用按钮,您可以使用
行<Button x:Name="btnOK" Content="OK" IsDefault="True" Click="btnOK_Click">
<Button.Style>
<Style TargetType="{x:Type Button}">
<Setter Property="IsEnabled" Value="false" />
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding ElementName=txt1, Path=(Validation.HasError)}" Value="false" />
<Condition Binding="{Binding ElementName=txt2, Path=(Validation.HasError)}" Value="false" />
</MultiDataTrigger.Conditions>
<Setter Property="IsEnabled" Value="true" />
</MultiDataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
或者您可以实现ICommand并使用命令绑定。
修改强>
这是一个完整的例子。它显示一个带有两个TextBox的窗口。当且仅当两个TextBox都非空时,才启用Button。创建一个名为ValidationDemo的项目,并将以下文件放入其中:
<强> MainWindow.xaml:强>
<Window x:Class="ValidationDemo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="146" Width="223">
<Window.Resources>
<Style TargetType="{x:Type TextBox}">
<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>
</Window.Resources>
<Grid>
<Label Content="A" Height="28" HorizontalAlignment="Left" Margin="46,7,0,0" Name="label1" VerticalAlignment="Top" />
<TextBox Name="txtA" Text="{Binding Path=TextA, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True, ValidatesOnExceptions=True}" Height="23" HorizontalAlignment="Left" Margin="69,12,0,0" VerticalAlignment="Top" Width="120" />
<Label Content="B" Height="28" HorizontalAlignment="Left" Margin="46,39,0,0" Name="label2" VerticalAlignment="Top" />
<TextBox Name="txtB" Text="{Binding Path=TextB, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True, ValidatesOnExceptions=True}" Height="23" HorizontalAlignment="Left" Margin="69,41,0,0" VerticalAlignment="Top" Width="120" />
<Button Name="btnOk" Content="OK" Height="23" HorizontalAlignment="Left" Margin="114,70,0,0" VerticalAlignment="Top" Width="75" Click="btnOk_Click">
<Button.Style>
<Style TargetType="{x:Type Button}">
<Setter Property="IsEnabled" Value="false" />
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding ElementName=txtA, Path=(Validation.HasError)}" Value="false" />
<Condition Binding="{Binding ElementName=txtB, Path=(Validation.HasError)}" Value="false" />
</MultiDataTrigger.Conditions>
<Setter Property="IsEnabled" Value="true" />
</MultiDataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
</Grid>
</Window>
<强> MainWindow.xaml.cs:强>
using System.Windows;
namespace ValidationDemo
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
private Model model = new Model();
public MainWindow()
{
InitializeComponent();
this.DataContext = this.model;
}
private void btnOk_Click(object sender, RoutedEventArgs e)
{
Application.Current.Shutdown();
}
}
}
<强> Model.cs:强>
using System;
using System.ComponentModel;
namespace ValidationDemo
{
public class Model : INotifyPropertyChanged, IDataErrorInfo
{
public event PropertyChangedEventHandler PropertyChanged;
private string textA = string.Empty;
public string TextA
{
get
{
return this.textA;
}
set
{
if (this.textA != value)
{
this.textA = value;
this.OnPropertyChanged("TextA");
}
}
}
private string textB = string.Empty;
public string TextB
{
get
{
return this.textB;
}
set
{
if (this.textB != value)
{
this.textB = value;
this.OnPropertyChanged("TextB");
}
}
}
public string Error
{
get { throw new NotImplementedException(); }
}
public string this[string columnName]
{
get
{
string result = string.Empty;
switch (columnName)
{
case "TextA":
if (string.IsNullOrEmpty(this.textA))
{
result = "'A' must not be empty";
}
break;
case "TextB":
if (string.IsNullOrEmpty(this.textA))
{
result = "'B' must not be empty";
}
break;
}
return result;
}
}
protected virtual void OnPropertyChanged(string propertyName)
{
if (this.PropertyChanged != null)
{
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}
答案 1 :(得分:5)
<Window.Resources>
<Style x:Key="ElementInError" TargetType="{x:Type FrameworkElement}">
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="True">
<Setter Property="ToolTip"
Value="{Binding (Validation.Errors)[0].ErrorContent, RelativeSource={x:Static RelativeSource.Self}}"/>
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
<!-- ... -->
<TextBox x:Name="txtName" Style="{StaticResource ElementInError}">
<!-- ... -->
</TextBox>
<!-- ... -->
<Button x:Name="OkButton" Content="Ok" Margin="5" Click="OkButton_Click">
<Button.Style>
<Style TargetType="Button">
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=txtName,Path=(Validation.HasError)}" Value="True">
<Setter Property="IsEnabled" Value="False" />
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
答案 2 :(得分:2)
如果您创建验证摘要,则可以将“运行”按钮的IsEnabled
属性绑定到其HasErrors
属性。
当IsEnabled
为假时,您需要使用中间属性或转换器,true
为HasErrors
。反之亦然。