我在设置页面中所有文本框的自定义验证规则时遇到问题。
我知道如何为1个单一文本框设置它:
<TextBox Margin="79,118,79,121" Name="textBox1" Style="{Binding EmptyTextboxValidator, UpdateSourceTrigger=PropertyChanged}">
<TextBox.Text>
<Binding Path="Text" UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<validators:StringRangeValidationRule MinimumLength="1" ErrorMessage="Text is te kort" />
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
但是,如果我需要为每个单独的文本框添加此代码,我不确定这是否有用,因为它将是一个非常多的复制粘贴。必须有一个更简单的方法吗?
如果进行了大量搜索,但我找不到为所有文本框设置它的示例,只有示例为1个单一文本框设置它(如上所示)
这是文本框样式的代码:
<Application.Resources>
<Style x:Key="EmptyTextboxValidator" TargetType="{x:Type TextBox}">
<Setter Property="Validation.ErrorTemplate">
<Setter.Value>
<ControlTemplate>
<DockPanel LastChildFill="True">
<Border BorderBrush="Red" BorderThickness="3">
<AdornedElementPlaceholder Name="MyAdorner" />
</Border>
</DockPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="true">
<Setter Property="ToolTip"
Value="{Binding RelativeSource={RelativeSource Self},
Path=(Validation.Errors)[0].ErrorContent}"/>
</Trigger>
</Style.Triggers>
</Style>
</Application.Resources>
以及验证规则的代码:
using System;
using System.Windows.Controls;
using System.Globalization;
namespace MyValidators
{
public class StringRangeValidationRule : ValidationRule
{
private int _minimumLength = 1;
private string _errorMessage;
public int MinimumLength
{
get { return _minimumLength; }
set { _minimumLength = value; }
}
public string ErrorMessage
{
get { return _errorMessage; }
set { _errorMessage = value; }
}
public override ValidationResult Validate(object value, CultureInfo cultureInfo)
{
ValidationResult result = new ValidationResult(true, null);
string inputString = (value ?? string.Empty).ToString();
if (string.IsNullOrEmpty(inputString) || inputString.Length < MinimumLength)
{
result = new ValidationResult(false, this.ErrorMessage);
}
return result;
}
}
}
viewModel:
public class Data : INotifyPropertyChanged
{
private int id = -1;
private bool updated = true;
private string text;
private string name;
public int ID
{
get
{
return id;
}
set
{
id = value;
OnPropertyChanged("ID");
}
}
public bool Updated
{
get
{
return updated;
}
set
{
updated = value;
}
}
public string Text
{
get
{
return text;
}
set
{
text = value;
OnPropertyChanged("Text");
}
}
public string Name
{
get
{
return name;
}
set
{
name = value;
OnPropertyChanged("Name");
}
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
updated = true;
}
#endregion
}
此外,我对xaml的了解有限,此代码是我为了更多地了解xaml而进行的测试的一部分。
也可能只有一种方法可以在文本框中添加字段,例如:
<TextBox ValidateStringLength="true"/>
甚至更好,如果我可以给它一个整数参数的字符串的最小长度:
<TextBox ValidateStringLength="5"/>
2中的任何一个(将其设置为我正在进行但是对于所有文本框一次)或上面演示的示例将非常感激。
答案 0 :(得分:2)
该解决方案称为BindingGroup。看看这段代码:
<StackPanel Name="stackPanel1">
<StackPanel.BindingGroup>
<BindingGroup NotifyOnValidationError="True">
<BindingGroup.ValidationRules>
<src:ValidateDateAndPrice ValidationStep="ConvertedProposedValue" />
</BindingGroup.ValidationRules>
</BindingGroup>
</StackPanel.BindingGroup>
<HeaderedContentControl Header="Price">
<TextBox Name="priceField" Width="150">
<TextBox.Text>
<Binding Path="Price" Mode="TwoWay" />
</TextBox.Text>
</TextBox>
</HeaderedContentControl>
<HeaderedContentControl Header="Date Offer Ends">
<TextBox Name="dateField" Width="150" >
<TextBox.Text>
<Binding Path="OfferExpires" StringFormat="d" />
</TextBox.Text>
</TextBox>
</HeaderedContentControl>
<StackPanel Orientation="Horizontal">
<Button IsDefault="True" Click="Submit_Click">_Submit</Button>
<Button IsCancel="True" Click="Cancel_Click">_Cancel</Button>
</StackPanel>
</StackPanel>
所有TextBox都有ValidateDateAndPrice ValidationRule。
您还可以控制何时保存更改。
private void Submit_Click(object sender, RoutedEventArgs e)
{
if (stackPanel1.BindingGroup.CommitEdit())
{
MessageBox.Show("Item submitted");
stackPanel1.BindingGroup.SubmitEdit();
}
}
在这种情况下,点击按钮时会提交更改。
修改强>
我发现你不知道你在做什么。
请在使用之前仔细阅读您想要使用的内容。
我将举例说明如何使其发挥作用。我用你的代码创建了这个例子。
<Window>
....
<Window.Resources>
<Style TargetType="{x:Type TextBox}">
<Setter Property="Validation.ErrorTemplate">
<Setter.Value>
<ControlTemplate>
<DockPanel LastChildFill="True">
<Border BorderBrush="Blue" BorderThickness="3">
<AdornedElementPlaceholder Name="MyAdorner" />
</Border>
</DockPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="true">
<Setter Property="ToolTip"
Value="{Binding RelativeSource={RelativeSource Self},
Path=(Validation.Errors)[0].ErrorContent}"/>
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
<Window.BindingGroup>
<BindingGroup>
<BindingGroup.ValidationRules>
<local:StringRangeValidationRule MinimumLength="5" ErrorMessage="Text too long!" />
</BindingGroup.ValidationRules>
</BindingGroup>
</Window.BindingGroup>
<Grid Margin="10" >
<TextBox Margin="100, 5, 0, 0" HorizontalAlignment="Left" VerticalAlignment="Top"
Text="{Binding Name}" Validation.ValidationAdornerSiteFor="{Binding ElementName=window}">
</TextBox>
<Button Content="Save" Click="Button_Click" Margin="0, 5, 100, 0" HorizontalAlignment="Right" VerticalAlignment="Top"/>
</Grid>
您需要在窗口中使用模板和样式才能使其正常工作。
这是背后的代码:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.DataContext = new Data() { Name = "Hello World!" };
}
private void Button_Click(object sender, RoutedEventArgs e)
{
window.BindingGroup.CommitEdit();
}
}
public class Data : INotifyPropertyChanged
{
private int id = -1;
private bool updated = true;
private string text;
private string name;
public int ID
{
get
{
return id;
}
set
{
id = value;
OnPropertyChanged("ID");
}
}
public bool Updated
{
get
{
return updated;
}
set
{
updated = value;
}
}
public string Text
{
get
{
return text;
}
set
{
text = value;
OnPropertyChanged("Text");
}
}
public string Name
{
get
{
return name;
}
set
{
name = value;
OnPropertyChanged("Name");
}
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
updated = true;
}
#endregion
}
public class StringRangeValidationRule : ValidationRule
{
private int _minimumLength = 1;
private string _errorMessage;
public int MinimumLength
{
get { return _minimumLength; }
set { _minimumLength = value; }
}
public string ErrorMessage
{
get { return _errorMessage; }
set { _errorMessage = value; }
}
public override ValidationResult Validate(object value, CultureInfo cultureInfo)
{
BindingGroup group = (BindingGroup)value;
var item = group.Items[0];
string inputString = (group.GetValue(item, "Name") ?? string.Empty).ToString();
if (true || string.IsNullOrEmpty(inputString) || inputString.Length < MinimumLength)
{
return new ValidationResult(false, this.ErrorMessage);
}
return ValidationResult.ValidResult;
}
}
如您所见,我更改了验证规则,并添加了Validation.ValidationAdornerSiteFor以指示TextBox应显示错误。
你应该能够复制过去,它会起作用。