WPF Binding 用于数据有效性校验的关卡是它的 ValidationRules 属性,用于数据类型转换的关卡是它的 Converter 属性。下面是实例:
1. Binding 的数据校验
<Window x:Class="WpfStudy.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfStudy"
Title="MainWindow"
Height="266" Width="300">
<StackPanel>
<TextBox x:Name="textBox1" Margin="5"/>
<Slider x:Name="slider1" Minimum="0" Maximum="100" Margin="5"/>
</StackPanel>
</Window>
知识兔 public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
Binding binding = new Binding("Value") { Source = this.slider1 };
binding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
binding.NotifyOnValidationError = true;
RangeValidationRule rvr = new RangeValidationRule();
rvr.ValidatesOnTargetUpdated = true;
binding.ValidationRules.Add(rvr);
this.textBox1.SetBinding(TextBox.TextProperty, binding);
this.textBox1.AddHandler(Validation.ErrorEvent, new RoutedEventHandler(this.ValidationError));
}
public void ValidationError(object sender, RoutedEventArgs e)
{
if (Validation.GetErrors(this.textBox1).Count > 0)
{
this.textBox1.ToolTip = Validation.GetErrors(this.textBox1)[0].ErrorContent.ToString();
}
}
}
知识兔 public class RangeValidationRule : ValidationRule
{
//需要实现 Validate 方法
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, "Validation Failed");
}
}
知识兔2. Binding 的数据转换
<Window x:Class="WpfStudy.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfStudy"
Title="MainWindow"
Height="266" Width="300">
<Window.Resources>
<local:CategoryToSourceConverter x:Key="cts"/>
<local:StateToNullableBoolConverter x:Key="stnb"/>
</Window.Resources>
<StackPanel Background="LightBlue">
<ListBox x:Name="listBoxPanel" Height="160" Margin="5">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Width="20" Height="20" Source="{Binding Path=Category,Converter={StaticResource cts}}"/>
<TextBlock Text="{Binding Path=Name}" Width="60" Margin="80,0"/>
<CheckBox IsThreeState="True" IsChecked="{Binding Path=State,Converter={StaticResource stnb}}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<Button x:Name="buttonLoad" Content="Load" Height="25" Margin="5,0" Click="ButtonLoad_Click"/>
<Button x:Name="buttonSave" Content="Save" Height="25" Margin="5,5" Click="ButtonSave_Click"/>
</StackPanel>
</Window>
知识兔 public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void ButtonLoad_Click(object sender, RoutedEventArgs e)
{
List<Plane> planeList = new List<Plane>()
{
new Plane() { Category = Category.Bomber, Name = "B-1", State = State.Unknown },
new Plane() { Category = Category.Bomber, Name = "B-2", State = State.Unknown },
new Plane() { Category = Category.Fighter, Name = "F-22", State = State.Unknown },
new Plane() { Category = Category.Fighter, Name = "Su-47", State = State.Unknown },
new Plane() { Category = Category.Bomber, Name = "B-52", State = State.Unknown },
new Plane() { Category = Category.Fighter, Name = "J-10", State = State.Unknown }
};
this.listBoxPanel.ItemsSource = planeList;
}
private void ButtonSave_Click(object sender, RoutedEventArgs e)
{
StringBuilder sb = new StringBuilder();
foreach(Plane p in listBoxPanel.Items)
{
sb.AppendLine(string.Format("Category={0},Name={1},State={2}", p.Category, p.Name, p.State));
}
File.WriteAllText(@"D:\PlaneList.txt", sb.ToString());
}
}
知识兔 // Converters
public class CategoryToSourceConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo cultureinfo)
{
Category c = (Category)value;
switch (c)
{
case Category.Bomber:
return @"\Icons\Bomber.png";
case Category.Fighter:
return @"\Icons\Fighter.png";
default:
return null;
}
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo cultureinfo)
{
throw new NotImplementedException();
}
}
public class StateToNullableBoolConverter : IValueConverter
{
// 将 State 转换为 bool?
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
State s = (State)value;
switch (s)
{
case State.Locked:
return false;
case State.Available:
return true;
case State.Unknown:
default:
return null;
}
}
// 将 bool? 转换为 State
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
bool? nb = (bool?)value;
switch (nb)
{
case true:
return State.Available;
case false:
return State.Locked;
case null:
default:
return State.Unknown;
}
}
}
知识兔 //种类
public enum Category
{
Bomber,
Fighter
}
//状态
public enum State
{
Available,
Locked,
Unknown
}
//飞机
public class Plane
{
public Category Category { get; set; }
public string Name { get; set; }
public State State { get; set; }
}
知识兔转自:《深入浅出 WPF》 第六章