首先 TextBox驗證不通過的觸發樣式--> 從網上找的代碼段
引用:
xmlns:Microsoft_Windows_Themes="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero"
樣式:
<LinearGradientBrush x:Key="TextBoxBorder" EndPoint="0,20" StartPoint="0,0" MappingMode="Absolute">
<GradientStop Color="#ABADB3" Offset="0.05"/>
<GradientStop Color="#E2E3EA" Offset="0.07"/>
<GradientStop Color="#E3E9EF" Offset="1"/>
</LinearGradientBrush>
<Style BasedOn="{x:Null}" TargetType="{x:Type TextBox}">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"/>
<Setter Property="BorderBrush" Value="{StaticResource TextBoxBorder}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Padding" Value="1"/>
<Setter Property="AllowDrop" Value="true"/>
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}">
<Grid x:Name="root">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="1"/>
</Grid.ColumnDefinitions>
<Microsoft_Windows_Themes:ListBoxChrome x:Name="Bd" SnapsToDevicePixels="true" Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"
RenderFocused="{TemplateBinding IsKeyboardFocusWithin}" RenderMouseOver="{TemplateBinding IsMouseOver}">
<ScrollViewer x:Name="PART_ContentHost" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</Microsoft_Windows_Themes:ListBoxChrome>
<Border x:Name="border" BorderBrush="#FFDB000C" BorderThickness="1" CornerRadius="1" Visibility="Collapsed" HorizontalAlignment="Stretch" Margin="0" Width="Auto">
<Grid Background="Transparent" HorizontalAlignment="Right" Height="12" Margin="1,-4,-4,0" VerticalAlignment="Top" Width="12">
<Path Data="M 1,0 L6,0 A 2,2 90 0 1 8,2 L8,7 z" Fill="#FFDC000C" Margin="1,3,0,0"/>
<Path Data="M 0,0 L2,0 L 8,6 L8,8" Fill="#ffffff" Margin="1,3,0,0"/>
</Grid>
</Border>
<Popup AllowsTransparency="True" x:Name="popup" Placement="Bottom" IsOpen="False">
<Border x:Name="border1_Copy" Width="Auto" Height="Auto" Background="Transparent" BorderThickness="0" BorderBrush="Transparent">
<TextBlock Margin="0,1,0,0" TextWrapping="NoWrap" Foreground="Red" Text="{Binding (Validation.Errors)[0].ErrorContent, RelativeSource={RelativeSource TemplatedParent}}" HorizontalAlignment="Center" VerticalAlignment="Center" />
</Border>
</Popup>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="Validation.HasError" Value="True">
<Setter Property="Visibility" TargetName="border" Value="Visible"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="Validation.HasError" Value="True"/>
<Condition Property="IsFocused" Value="True"/>
</MultiTrigger.Conditions>
<Setter Property="IsOpen" TargetName="popup" Value="True"/>
</MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
一個類的屬性驗證可能會發生 多個屬性值互相關聯的情況
比如 a、b、c 、d 四個屬性值:d<c<b<a
則用ValidationAttribute 方式驗證 直接在屬性值上面驗證方式需要自定義 驗證類
public class Example: INotifyPropertyChanged , IDataErrorInfo
{
private int _b;
[ValidateRelation("A", "C", 100, 1)] //A、C為待驗證關聯屬性名
public int B{
get { return _b; }
set
{
if (_b != value)
{
_b = value;
OnPropertyChanged(new PropertyChangedEventArgs("B"));
}
}
}
驗證類:
//ValidateRelation
using System.ComponentModel.DataAnnotations;
/// <summary>
///關聯驗證類
/// </summary>
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false)] //指定在那些元素可以使用該特性
public class ValidateRelation : ValidationAttribute
{
public ValidateRelation(string lessComparePropertyPara,string moreComparePropertyPara,int maxValuePara,int minValuePara)
{
LessCompareProperty = lessComparePropertyPara;
MoreCompareProperty = moreComparePropertyPara;
MaxValue = maxValuePara;
MinValue = minValuePara;
}
/// <summary>
/// 比較的值 的屬性名稱(比較對象) 目前值小于 lessCompareProperty則驗證通過
/// </summary>
public string LessCompareProperty { get; set; }
/// <summary>
/// 比較的值 的屬性名稱(比較對象)目前值大于 MoreCompareProperty則驗證通過
/// </summary>
public string MoreCompareProperty { get; set; }
/// <summary>
/// 比較大小 最大值
/// </summary>
public int MaxValue { get; set; }
/// <summary>
/// 比較大小 最小值
/// </summary>
public int MinValue { get; set; }
/// <summary>
/// 此方法先于 IsValid(object value)調用
/// </summary>
/// <param name="value"></param>
/// <param name="validationContext"></param>
/// <returns></returns>
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
var curCompareValue = (int)value;//目前待驗證的值
//validationContext.ObjectInstance 待驗證對象
//validationContext.ObjectType 待驗證對象類型
var tempData = Convert.ChangeType(validationContext.ObjectInstance, validationContext.ObjectType);//建立待驗證對象
bool isInt = false;
int lessCompareValue = -1;
PropertyInfo lessPropertyInfo = null;
if (LessCompareProperty != "")
{
lessPropertyInfo = validationContext.ObjectType.GetProperty(LessCompareProperty); //擷取指定名稱的屬性
isInt = int.TryParse(lessPropertyInfo.GetValue(tempData, null).ToString(), out lessCompareValue);
}
int moreCompareValue = -1;
PropertyInfo morePropertyInfo = null;
if (MoreCompareProperty!="")
{
morePropertyInfo = validationContext.ObjectType.GetProperty(MoreCompareProperty); //擷取指定名稱的屬性
isInt = int.TryParse(morePropertyInfo.GetValue(tempData, null).ToString(), out moreCompareValue);
}
if (!isInt) //擷取屬性值
{
//如果類型不正确
return new ValidationResult($"{LessCompareProperty}不是整型");
}
else
{
//首先比較大小 比較大小 比較通過 則 繼續走else
if (!ValidateIntCommon.CheckIntValue(value, MaxValue, MinValue))
{
return new ValidationResult($"該項值範圍(" + MinValue + "-" + MaxValue + ")");
}
else
{
//比較2個值 傳回錯誤消息
//可以根據業務自定義添加參數 比較是否需要等于
if (curCompareValue >= lessCompareValue && lessCompareValue > 0)
{
if (LessCompareProperty.ToLower().Contains("A"))
{
return new ValidationResult($"該項值小于A");
}
else
{
return new ValidationResult($"該項值輸入的值錯誤");
}
}
else if (curCompareValue <= moreCompareValue && moreCompareValue >= 0)
{
if (MoreCompareProperty.ToLower().Contains("C"))
{
return new ValidationResult($"該項值大于C");
}
else
{
return new ValidationResult($"該項值輸入的值錯誤");
}
}
else
{
return base.IsValid(value, validationContext);
}
}
}
}
public override bool IsValid(object value)
{
return ValidateIntCommon.CheckIntValue(value, MaxValue, MinValue);
}
}
前端引用:
<TextBox x:Name="tb_B" Text="{Binding B,Mode=TwoWay, UpdateSourceTrigger=PropertyChanged,ValidatesOnDataErrors=True}"/>