淺析WPF中Binding的數(shù)據(jù)校驗(yàn)和類型轉(zhuǎn)換
在WPF開發(fā)中,Binding實(shí)現(xiàn)了數(shù)據(jù)在Source和Target之間的傳遞和流通,就像現(xiàn)實(shí)生活中的一條條道路,建立起了城鎮(zhèn)與城鎮(zhèn)之間的銜接,而數(shù)據(jù)校驗(yàn)和類型轉(zhuǎn)換,就像高速公路之間的收費(fèi)站和安檢站。那在WPF開發(fā)中,如何實(shí)現(xiàn)數(shù)據(jù)的校驗(yàn)和類型轉(zhuǎn)換呢?本文以一個簡單的小例子,簡述在WPF開發(fā)中,實(shí)現(xiàn)數(shù)據(jù)校驗(yàn)和類型轉(zhuǎn)換的相關(guān)知識點(diǎn),僅供學(xué)習(xí)分享使用,如有不足之處,還請指正。
數(shù)據(jù)校驗(yàn)
在WPF開發(fā)中,校驗(yàn)數(shù)據(jù)的有效性,主要步驟如下:
1. 實(shí)現(xiàn)校驗(yàn)規(guī)則
Binding的ValidationRules是Collection<ValidationRule>類型,是一個校驗(yàn)規(guī)則列表,可以支持多重校驗(yàn)。而ValidationRule是一個抽象類,所有要實(shí)現(xiàn)業(yè)務(wù)規(guī)則校驗(yàn),就要繼承ValidationRule并實(shí)現(xiàn)抽象方法。
ValidationRule的Validate方法返回一個ValidationResult對象,如果校驗(yàn)通過,則ValidationResult的IsValid為true,否則為false。RangeValidationRule主要校驗(yàn)用戶輸入數(shù)據(jù)的范圍:
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Controls;
namespace WpfApp4.DataValidate
{
public class RangeValidationRule : ValidationRule
{
public override ValidationResult Validate(object value, CultureInfo cultureInfo)
{
double d = 0;
if(double.TryParse(value.ToString(),out d))
{
if(d>=0 && d <= 100)
{
return new ValidationResult(true,null);
}
}
return new ValidationResult(false, "數(shù)據(jù)必須在0~100之間");
}
}
}2. 設(shè)置規(guī)則
要想應(yīng)用規(guī)則,首先需要引入規(guī)則對應(yīng)的命名空間:xmlns:v="clr-namespace:WpfApp4.DataValidate"
然后設(shè)置Binding的ValidationRules規(guī)則,如下所示:
<TextBlock Text="年齡" VerticalAlignment="Center"></TextBlock>
<TextBox x:Name="tbAge" Width="120" Height="25" Margin="10" Validation.Error="tbAge_Error" VerticalContentAlignment="Center">
<TextBox.Text>
<Binding Path="Age" UpdateSourceTrigger="PropertyChanged" NotifyOnValidationError="True">
<Binding.ValidationRules>
<v:RangeValidationRule ValidatesOnTargetUpdated="True"></v:RangeValidationRule>
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
<TextBlock VerticalAlignment="Center" Text="{Binding DataError}" Foreground="Red"></TextBlock>關(guān)于校驗(yàn)規(guī)則,有以下幾點(diǎn)需要注意:
默認(rèn)情況下,認(rèn)為Source的數(shù)據(jù)總是正確的,規(guī)則校驗(yàn)只有當(dāng)Target更新時,才會生效,因?yàn)門arget多為用戶輸入;如果當(dāng)Source更新時也要生效,則需要配置ValidatesOnTargetUpdated為true。
默認(rèn)情況下,校驗(yàn)規(guī)則返回的錯誤信息,是不會輸出到UI的,如果要輸出要UI,需要設(shè)置NotifyOnValidationError屬性為true。
3. 輸出校驗(yàn)信息
默認(rèn)情況下,校驗(yàn)信息不會輸出到UI,只是顯示用戶控件為紅色邊框,如果要輸出校驗(yàn)信息,除了設(shè)置NotifyOnValidationError屬性外,還要訂閱Validation.Error事件,并在事件中處理要顯示的錯誤信息,如下所示:
private void tbAge_Error(object sender, ValidationErrorEventArgs e)
{
this.viewModel.ValidationErrorCommand.Execute(e);
}其中上述方法中的命令為ViewModel中定義,如下所示:
public class MainWindowViewModel : ObservableObject
{
private int age;
public int Age
{
get { return age; }
set { SetProperty(ref age , value); }
}
private string dataError;
public string DataError
{
get { return dataError; }
set { SetProperty(ref dataError , value); }
}
private TextBox textBox;
private ICommand winLoadedCommand;
public ICommand WinLoadedCommand
{
get {
if (winLoadedCommand == null)
{
winLoadedCommand = new RelayCommand<object>(WinLoaded);
}
return winLoadedCommand; }
}
private void WinLoaded(object sender)
{
if (sender != null)
{
var win = sender as MainWindow;
this.textBox = win.tbAge;
}
}
private ICommand validationErrorCommand;
public ICommand ValidationErrorCommand
{
get {
if (validationErrorCommand == null)
{
validationErrorCommand = new RelayCommand<object>(DisplayValidationError);
}
return validationErrorCommand; }
}
private void DisplayValidationError(object obj)
{
if (Validation.GetErrors(this.textBox).Count > 0)
{
this.DataError= Validation.GetErrors(this.textBox)[0].ErrorContent.ToString();
}
else
{
this.DataError = string.Empty;
}
}
}4. 數(shù)據(jù)校驗(yàn)示例演示
經(jīng)過上述步驟,運(yùn)行程序,如下所示:

數(shù)據(jù)類型轉(zhuǎn)換
在數(shù)據(jù)綁定時,如果Source端的數(shù)據(jù)類型和Target端的數(shù)據(jù)類型不一致時,就需要用到數(shù)據(jù)類型轉(zhuǎn)換,如:true/false與顯示/隱藏之間的轉(zhuǎn)換等,要實(shí)現(xiàn)數(shù)據(jù)轉(zhuǎn)換,需要用到Binding的Converter屬性。步驟如下:
1. 定義轉(zhuǎn)換器
Binding的Converter屬性是IValueConverter類型,所以定義轉(zhuǎn)換器需要實(shí)現(xiàn)IValueConverter接口,如下所示:
namespace WpfApp4.DataConverter
{
public class BoolToVisilityConverter : IValueConverter
{
/// <summary>
/// Source 到 Target
/// </summary>
/// <param name="value"></param>
/// <param name="targetType"></param>
/// <param name="parameter"></param>
/// <param name="culture"></param>
/// <returns></returns>
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var flag = bool.Parse(value.ToString());
if(flag)
{
return Visibility.Visible;
}
else
{
return Visibility.Collapsed;
}
}
/// <summary>
/// Target到Source
/// </summary>
/// <param name="value"></param>
/// <param name="targetType"></param>
/// <param name="parameter"></param>
/// <param name="culture"></param>
/// <returns></returns>
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
var visibility = Visibility.Collapsed;
if (Enum.TryParse<Visibility>(value.ToString(), out visibility))
{
if (visibility == Visibility.Collapsed)
{
return false;
}
else if(visibility == Visibility.Visible)
{
return true;
}
else
{
return false;
}
}
return false;
}
}
}注意:IValueConverter接口共兩個方法,其中Convert方法當(dāng)Source到Target時調(diào)用,ConvertBack方法則是反方向調(diào)用。
2. 定義資源
轉(zhuǎn)換器也是一種資源,要聲明資源,首先引入命名空間xmlns:c="clr-namespace:WpfApp4.DataConverter",如下所示:
<Window.Resources> <c:BoolToVisilityConverter x:Key="boolToVisility"></c:BoolToVisilityConverter> </Window.Resources>
3. 調(diào)用類型轉(zhuǎn)換
在Binding時,調(diào)用資源Visibility="{Binding ElementName=chk01, Path=IsChecked, Converter={StaticResource boolToVisility}}"。通過復(fù)選框的選擇與否,控制控件的顯示與隱藏,如下所示:
<StackPanel Orientation="Horizontal" Grid.Row="0">
<CheckBox Content="顯示" x:Name="chk01"></CheckBox>
</StackPanel>
<StackPanel Orientation="Horizontal" Grid.Row="1" Visibility="{Binding ElementName=chk01, Path=IsChecked, Converter={StaticResource boolToVisility}}">
<TextBlock Text="年齡" VerticalAlignment="Center"></TextBlock>
<TextBox x:Name="tbAge" Width="120" Height="25" Margin="10" Validation.Error="tbAge_Error" VerticalContentAlignment="Center">
<TextBox.Text>
<Binding Path="Age" UpdateSourceTrigger="PropertyChanged" NotifyOnValidationError="True">
<Binding.ValidationRules>
<v:RangeValidationRule ValidatesOnTargetUpdated="True"></v:RangeValidationRule>
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
<TextBlock VerticalAlignment="Center" Text="{Binding DataError}" Foreground="Red"></TextBlock>
</StackPanel>4. 數(shù)據(jù)類型轉(zhuǎn)換示例演示

到此這篇關(guān)于淺析WPF中Binding的數(shù)據(jù)校驗(yàn)和類型轉(zhuǎn)換的文章就介紹到這了,更多相關(guān)WPF Binding內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
.Net(c#)漢字和Unicode編碼互相轉(zhuǎn)換實(shí)例
下面小編就為大家?guī)硪黄?Net(c#)漢字和Unicode編碼互相轉(zhuǎn)換實(shí)例。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-02-02
c# Selenium爬取數(shù)據(jù)時防止webdriver封爬蟲的方法
這篇文章主要介紹了c# Selenium爬取數(shù)據(jù)時防止webdriver封爬蟲的方法,幫助大家更好的理解和使用c#,感興趣的朋友可以了解下2021-01-01
winform用datagridview制作課程表實(shí)例
這篇文章主要介紹了winform用datagridview制作課程表的方法,實(shí)例分析了WinForm實(shí)現(xiàn)課程表的結(jié)構(gòu)、數(shù)據(jù)庫及調(diào)用技巧,需要的朋友可以參考下2015-01-01
.NET中實(shí)現(xiàn)彩色光標(biāo)、動畫光標(biāo)及自定義光標(biāo)的方法
這篇文章主要介紹了.NET中實(shí)現(xiàn)彩色光標(biāo)、動畫光標(biāo)及自定義光標(biāo)的方法,非常實(shí)用的功能,需要的朋友可以參考下2014-08-08
C#實(shí)現(xiàn)路由器斷開連接,更改公網(wǎng)ip的實(shí)例代碼
C#實(shí)現(xiàn)路由器斷開連接,更改公網(wǎng)ip的實(shí)例代碼,需要的朋友可以參考一下2013-05-05

