我正在创建一个我想使用验证规则的应用程序,但是在某些屏幕上没有足够的空间来显示错误字段旁边的结果错误,所以我想把它放在底部的状态栏中场地。
这个示例来自我从网络上拼凑的几个位,它提供了一个使用不同规则进行验证并以不同方式显示错误的表单,但我看不到如何使用 XAML 将错误消息放入 StatusBarItem。我确信有一种简单的方法可以做到这一点。任何人都可以帮助我吗?
该示例是在 VS2010 中使用 Framework 4.0 编写的。
主窗口.xaml
<Window x:Class="SampleValidation.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:c="clr-namespace:SWL.Libraries.SysText"
Title="Sample ValidationRule WPF" Height="350" Width="525"
Loaded="Window_Loaded" WindowStartupLocation="CenterScreen">
<Window.Resources>
<ControlTemplate x:Key="validationTemplate">
<!--
<TextBlock Foreground="Red" FontSize="20">***</TextBlock>
-->
<DockPanel LastChildFill="True">
<TextBlock DockPanel.Dock="Right" Foreground="Red" Margin="5" FontSize="8pt" Text="***" />
<AdornedElementPlaceholder />
</DockPanel>
</ControlTemplate>
<Style x:Key="textBoxInError1" 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>
<Style x:Key="textBoxInError2" TargetType="{x:Type TextBox}">
<Setter Property="Validation.ErrorTemplate">
<Setter.Value>
<ControlTemplate>
<DockPanel LastChildFill="True">
<TextBlock DockPanel.Dock="Right" Foreground="Red" Margin="5" FontSize="8pt"
Text="{Binding ElementName=MyAdorner, Path=AdornedElement.(Validation.Errors)[0].ErrorContent}" />
<Border BorderBrush="Red" BorderThickness="2">
<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>
<Grid>
<TextBlock Height="24" HorizontalAlignment="Left" Margin="36,73,0,0" Name="textBlock1"
Text="Node Address:" VerticalAlignment="Top" Width="87" />
<TextBlock Height="24" HorizontalAlignment="Left" Margin="36,112,0,0" Name="textBlock2"
Text="Node Name:" VerticalAlignment="Top" Width="78" />
<TextBox Height="24" HorizontalAlignment="Left" Margin="129,70,0,0" Name="textBox1"
VerticalAlignment="Top" Width="119" TextChanged="textBox1_TextChanged"
TabIndex="0" Style="{StaticResource textBoxInError2}"
Validation.ErrorTemplate="{StaticResource validationTemplate}">
<Binding Path="NodeAddress" UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<c:NumberRangeRule Min="1" Max="100" />
</Binding.ValidationRules>
</Binding>
</TextBox>
<TextBox Height="24" HorizontalAlignment="Left" Margin="129,109,0,0" Name="textBox2"
VerticalAlignment="Top" Width="119" TextChanged="textBox2_TextChanged"
TabIndex="1" Style="{StaticResource textBoxInError2}">
<Binding Path="NodeName" UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<c:NameFormatRule MinLength="6" MaxLength="9" />
</Binding.ValidationRules>
</Binding>
</TextBox>
<StatusBar Height="23" HorizontalAlignment="Stretch" Margin="0,0,0,0"
Name="myStatusBar" VerticalAlignment="Bottom">
<StatusBarItem x:Name="errorStatusBarItem" Content="No errors" />
</StatusBar>
<Button Content="Close" Height="29" HorizontalAlignment="Left" Margin="108,227,0,0"
Name="btnCLOSE" VerticalAlignment="Top" Width="85" Click="btnCLOSE_Click" TabIndex="3" />
<Button Content="Apply" Height="29" HorizontalAlignment="Left" Margin="297,227,0,0"
Name="btnAPPLY" VerticalAlignment="Top" Width="85" Click="btnAPPLY_Click" TabIndex="2" />
</Grid>
</Window>
主窗口.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 SampleValidation {
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window {
public int NodeAddress { get; set; }
public string NodeName { get; set; }
public bool IsAllLoaded { get; set; }
public MainWindow() {
NodeAddress = 1;
NodeName = "freddy";
IsAllLoaded = false;
InitializeComponent();
btnAPPLY.Visibility = System.Windows.Visibility.Hidden;
DataContext = this;
}
private void btnAPPLY_Click(object sender, RoutedEventArgs e) {
// if there are no format errors reported by the validation rules
Validator.ErrorText = "";
if (Validator.IsValid(this))
// Save the data
btnAPPLY.Visibility = System.Windows.Visibility.Hidden; // hide the button indicating nothing new to save
else
MessageBox.Show("Cant Save Changes - Error in form\r\n" + Validator.ErrorText, "Save not allowed", MessageBoxButton.OK, MessageBoxImage.Error);
}
private void btnCLOSE_Click(object sender, RoutedEventArgs e) {
if (btnAPPLY.Visibility != System.Windows.Visibility.Hidden) {
MessageBoxResult myAnswer = MessageBox.Show("Save Changes?", "Confirmation", MessageBoxButton.YesNoCancel);
if (myAnswer == MessageBoxResult.Cancel)
return;
if (myAnswer == MessageBoxResult.Yes)
btnAPPLY_Click(sender, e);
}
this.Close();
}
private void Window_Loaded(object sender, RoutedEventArgs e) {
IsAllLoaded = true;
}
private void ShowModified() {
if (IsAllLoaded)
btnAPPLY.Visibility = System.Windows.Visibility.Visible;
} // ShowModified
private void textBox2_TextChanged(object sender, TextChangedEventArgs e) {
ShowModified();
}
private void textBox1_TextChanged(object sender, TextChangedEventArgs e) {
ShowModified();
}
} // class MainWindow
public static class Validator {
public static string ErrorText { get; set; }
static Validator() {
ErrorText = "";
}
public static bool IsValid(DependencyObject parent) {
// Validate all the bindings on the parent
bool valid = true;
LocalValueEnumerator localValues = parent.GetLocalValueEnumerator();
while (localValues.MoveNext()) {
LocalValueEntry entry = localValues.Current;
if (BindingOperations.IsDataBound(parent, entry.Property)) {
Binding binding = BindingOperations.GetBinding(parent, entry.Property);
if (binding.ValidationRules.Count > 0) {
BindingExpression expression = BindingOperations.GetBindingExpression(parent, entry.Property);
expression.UpdateSource();
if (expression.HasError) {
ErrorText = expression.ValidationError.ErrorContent.ToString();
valid = false;
}
}
}
}
// Validate all the bindings on the children
System.Collections.IEnumerable children = LogicalTreeHelper.GetChildren(parent);
foreach (object obj in children) {
if (obj is DependencyObject) {
DependencyObject child = (DependencyObject)obj;
if (!IsValid(child)) {
valid = false;
}
}
}
return valid;
}
} // class Validator
验证规则.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Globalization;
using System.Windows.Controls;
namespace SWL.Libraries.SysText {
public class NumberRangeRule : ValidationRule {
private int _min;
private int _max;
public NumberRangeRule() { }
public int Min {
get { return _min; }
set { _min = value; }
}
public int Max {
get { return _max; }
set { _max = value; }
}
public override ValidationResult Validate(object value, CultureInfo cultureInfo) {
int val = 0;
try {
if (((string)value).Length > 0)
val = Int32.Parse((String)value);
} catch (Exception e) {
return new ValidationResult(false, "Illegal Characters or " + e.Message);
}
if ((val < Min) || (val > Max)) {
return new ValidationResult(false, "Please Enter Number in Range: " + Min + " - " + Max + ".");
} else {
return new ValidationResult(true, null);
}
}
}
public class NameFormatRule : ValidationRule {
private int _minLength;
private int _maxLength;
public NameFormatRule() { }
public int MinLength {
get { return _minLength; }
set { _minLength = value; }
}
public int MaxLength
get { return _maxLength; }
set { _maxLength = value; }
}
public override ValidationResult Validate(object value, CultureInfo cultureInfo) {
try {
if (((string)value).Length > 0) {
if (((string)value).Length < MinLength || ((string)value).Length > MaxLength)
return new ValidationResult(false, String.Format ("Enter a string of {0} to {1} characters in length", MinLength, MaxLength));
return new ValidationResult(true, null);
}
return new ValidationResult(true, null);
} catch (Exception e) {
return new ValidationResult(false, "Illegal Characters or " + e.Message);
}
}
}
}