WPF基础 数据绑定与验证
数据绑定是WPF应用的关键.下面通过一段代码来重温基本绑定
1.基本数据绑定
1.1 提前准备的内容
- 数据实体类 Customer ,通过继承INotifyPropertyChanged接口,实现PropertyChangedEventHandler 委托的方法
using System;
using System.ComponentModel;
namespace SimpleBinding
{
public class Customer : INotifyPropertyChanged
{
private string _name;
public Customer()
{
}
public Customer( string value)
{
_name = value;
}
public string CustomerName
{
get { return _name; }
set
{
_name = value;
// Call OnPropertyChanged whenever the property is updated
OnPropertyChanged("CustomerName");
}
}
private int _age;
public int Age
{
get { return _age; }
set
{
_age = value;
OnPropertyChanged("Age");
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string name)
{
var handler = PropertyChanged;
handler?.Invoke(this, new PropertyChangedEventArgs(name));
}
}
}
1.2 前台数据绑定
- Step 1 定义数据源
<Window.Resources>
<!--绑定的资源对象 Person,必须有一个无参构造函数 -->
<local:Customer x:Key="MyDataSource" CustomerName="Joe" Age="10" />
</Window.Resources>
- Step2 绑定到界面控件
<Border Margin="5" BorderBrush="Red" BorderThickness="2" Padding="8" CornerRadius="20">
<StackPanel >
<Label>请输入姓名</Label>
<TextBox>
<TextBox.Text>
<Binding Source="{StaticResource MyDataSource}" Path="CustomerName" UpdateSourceTrigger="PropertyChanged"/>
</TextBox.Text>
</TextBox>
<Label>请输入年龄</Label>
<TextBox>
<TextBox.Text>
<Binding Source="{StaticResource MyDataSource}" Path="Age" UpdateSourceTrigger="PropertyChanged">
</Binding>
</TextBox.Text>
</TextBox>
<Label>输入的信息如下:</Label>
<TextBlock>
<Run Text="姓名:"/>
<TextBlock Text="{Binding Source={StaticResource MyDataSource}, Path=CustomerName}" />
<Run Text="年龄:"/>
<TextBlock Text="{Binding Source={StaticResource MyDataSource}, Path=Age}" />
</TextBlock>
</StackPanel>
- Step3 运行程序,可以看到,改变数据,相关绑定内容会随之变化.
1.3 数据验证
年龄输入10212,显然与实际不符,为更贴近实际,需要进一步增加验证功能.
- 自定义验证类 AgeRangeRule.cs
该类定义一个年龄的最大值和最小值,重写了验证规则
public class AgeRangeRule : ValidationRule
{
public int Min { get; set; }
public int Max { get; set; }
public override ValidationResult Validate(object value, CultureInfo cultureInfo)
{
var age = 0;
try
{
if (((string)value).Length > 0)
age = int.Parse((string)value);
}
catch (Exception e)
{
return new ValidationResult(false, "只能输出数字" + e.Message);
}
if ((age < Min) || (age > Max))
{
return new ValidationResult(false,
"请按范围输入年龄: " + Min + " - " + Max + ".");
}
return new ValidationResult(true, null);
}
}
}
- 修改窗口相关代码
修改后,xaml代码如下:
<Window x:Class="SimpleBinding.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:SimpleBinding"
mc:Ignorable="d" Height="300" Width="300" Title="MainWindow" >
<Window.Resources>
<!--绑定的资源对象 Person,必须有一个无参构造函数 -->
<local:Customer x:Key="MyDataSource" CustomerName="Joe" Age="10" />
</Window.Resources>
<Border Margin="5" BorderBrush="Red" BorderThickness="2" Padding="8" CornerRadius="20">
<StackPanel >
<Label>请输入姓名</Label>
<TextBox>
<TextBox.Text>
<Binding Source="{StaticResource MyDataSource}" Path="CustomerName" UpdateSourceTrigger="PropertyChanged"/>
</TextBox.Text>
</TextBox>
<Label>请输入年龄</Label>
<TextBox>
<TextBox.Text>
<Binding Source="{StaticResource MyDataSource}" Path="Age" UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<local:AgeRangeRule Min="10" Max="130"/>
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
<Label>输入的信息如下:</Label>
<TextBlock>
<Run Text="姓名:"/>
<TextBlock Text="{Binding Source={StaticResource MyDataSource}, Path=CustomerName}" />
<Run Text="年龄:"/>
<TextBlock Text="{Binding Source={StaticResource MyDataSource}, Path=Age}" />
</TextBlock>
</StackPanel>
</Border>
</Window>
再次运行
可以看到,当年龄输出小于10或者大于130的数据时,输入呈红色警告,当输入数值超出正常值范围外时,下面的输入信息显示不再变化.起到了初步的验证效果,但这并不是我想要的
继续优化!!
1.4 数据验证再优化 (Business Layer Validation)
-
资源中定义验证提供信息的样式
-
录入框TextBox 绑定定义的静态样式
-
效果如图,当出现错误时,鼠标在录入控件上悬停时,会出现提示框.提示信息来源于 AgeRangeRule 规则
2.绑定到数据选择控件 DataPickBinding
<Window x:Class="DataPickBinding.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:DataPickBinding"
mc:Ignorable="d"
Title="MainWindow" Height="200" Width="300">
<Window.Resources>
<Style TargetType="TextBlock">
<Setter Property="FontSize" Value="16"/>
<Setter Property="FontWeight" Value="Bold"/>
<Setter Property="DockPanel.Dock" Value="Top"/>
<Setter Property="HorizontalAlignment" Value="Center"/>
</Style>
<Style TargetType="Canvas">
<Setter Property="Height" Value="50"/>
<Setter Property="Width" Value="50"/>
<Setter Property="Margin" Value="8"/>
<Setter Property="DockPanel.Dock" Value="Top"/>
</Style>
<Style TargetType="ComboBox">
<Setter Property="Width" Value="150"/>
<Setter Property="Margin" Value="8"/>
<Setter Property="DockPanel.Dock" Value="Top"/>
</Style>
</Window.Resources>
<Border Margin="10" BorderBrush="Silver" BorderThickness="3" Padding="8">
<DockPanel>
<TextBlock>Choose a Color:</TextBlock>
<ComboBox Name="myComboBox" SelectedIndex="0">
<ComboBoxItem>Green</ComboBoxItem>
<ComboBoxItem>Blue</ComboBoxItem>
<ComboBoxItem>Red</ComboBoxItem>
</ComboBox>
<Canvas Width="150" Height="40" >
<Canvas.Background>
<Binding ElementName="myComboBox" Path="SelectedItem.Content"/>
</Canvas.Background>
</Canvas>
</DockPanel>
</Border>
</Window>
3.绑定到方法
新建TemperatureScale类,包含一个ConvertTemp方法
在xaml资源中定义表态方法引用,并定义2个参数初始值