Data Binding 数据绑定
Person person = new Person("Tom", 11); public MainWindow(IRegionManager regionManager) { InitializeComponent(); birthdayButton.Click += BirthdayButton_Click; this.DataContext = person;//设置上下文数据 }
绑定数据,其中 Path 可以省略
<TextBox Name="ageTextBox" Text="{Binding Path=Age, Mode=TwoWay}" >
<TextBox> <TextBox.Text> <Binding Path="Age" /> </TextBox.Text> </TextBox>
绑定模式
Mode:TwoWay(双击绑定,默认)、OneWay(单向绑定)、OneWayToSource(单向绑定,从UI元素更新到对象属性)、OneTime(绑定一次)
绑定到静态资源
<Window x:Class="WpfTestBlankApp.Views.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:WpfTestBlankApp.Models" xmlns:prism="http://prismlibrary.com/" prism:ViewModelLocator.AutoWireViewModel="True" Title="{Binding Title}" Height="350" Width="500" > <Window.Resources> <local:Person x:Key="Tom" Name="Tom88" Age="99"/> </Window.Resources> <StackPanel DataContext="{StaticResource Tom}"> <TextBlock >Name:</TextBlock> <TextBox Name="nameTextBox" Text="{Binding Path=Name}" /> <TextBlock >Age:</TextBlock> <TextBox Name="ageTextBox" Text="{Binding Path=Age, Mode=TwoWay}" > </TextBox> <Button Height="50" Name="birthdayButton" >Birthday</Button> </StackPanel> </Window>
当有多个数据源时,可以用 Source 属性显示设置数据源
<Window.Resources> <local:Person x:Key="Tom" Name="Tom88" Age="99"/> <local:Person x:Key="John" Name="John" Age="55"/> </Window.Resources> <StackPanel DataContext="{StaticResource Tom}"> <TextBlock >Name:</TextBlock> <TextBox Name="nameTextBox" Text="{Binding Path=Name, Source={StaticResource Tom}}" /> <TextBlock >Age:</TextBlock> <TextBox Name="ageTextBox" Text="{Binding Path=Age,Source={StaticResource John}, Mode=TwoWay }" > </TextBox> <Button Height="50" Name="birthdayButton" >Birthday</Button> </StackPanel>
将一个元素的属性绑定到另一个元素的属性
<TextBox Name="nameTextBox" Foreground="Red" Text="{Binding Path=Name}" /> <Button Foreground="{Binding Path=Foreground, ElementName=nameTextBox}" Height="50" Name="birthdayButton" >Birthday</Button>
当 nameTextBox 文本框前景色更改时,Button的前景色也随之变化。
类型转换
View Code
验证
XML中使用验证类
显示验证错误信息
View Code
View Code
绑定值类型转换
当绑定的元素的属性类型和对象的属性类型不一致时,需要类型转换。
//类型转换 [ValueConversion(typeof(int), typeof(Brush))] public class AgeToForegroundConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { if (targetType != typeof(Brush)) { return null; } int age = int.Parse(value.ToString()); return (age > 25 ? Brushes.Red : Brushes.Green); } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { throw new NotImplementedException(); } }
<Window.Resources> <local:Person x:Key="Tom" Name="Tom88" Age="99"/> <local:AgeToForegroundConverter x:Key="ageConverter"/> </Window.Resources> <StackPanel > <TextBlock >Name:</TextBlock> <TextBox Name="nameTextBox" Foreground="Red" Text="{Binding Path=Name}" /> <TextBlock >Age:</TextBlock> <TextBox Name="ageTextBox" Text="{Binding Path=Age}" Foreground="{Binding Path=Age, Converter={StaticResource ageConverter} }" > </TextBox> <Button Foreground="{Binding Path=Foreground, ElementName=ageTextBox}" Height="50" Name="birthdayButton" >Birthday</Button> </StackPanel>
对绑定元素实现自定义验证
1 public class NumberRangeRule : ValidationRule 2 { 3 int min; 4 public int Min 5 { 6 get { return min; } 7 set { min = value; } 8 } 9 int max; 10 public int Max 11 { 12 get { return max; } 13 set { max = value; } 14 } 15 public override ValidationResult Validate(object value, CultureInfo cultureInfo) 16 { 17 int number; 18 if(!int.TryParse((string)value, out number)) 19 { 20 return new ValidationResult(false, "无效的数字"); 21 } 22 if(number<min || number>max) 23 { 24 return new ValidationResult(false, $"超出范围({min}-{max})"); 25 } 26 return ValidationResult.ValidResult; 27 } 28 }
1 <TextBox Name="ageTextBox" > 2 <TextBox.Text> 3 <Binding Path="Age" NotifyOnValidationError="True" > 4 <Binding.ValidationRules> 5 <local:NumberRangeRule Min="0" Max="128"/> 6 </Binding.ValidationRules> 7 </Binding> 8 </TextBox.Text> 9 </TextBox>
1 public MainWindow(IRegionManager regionManager) 2 { 3 InitializeComponent(); 4 Validation.AddErrorHandler(this.ageTextBox, ageTextBox_ValidationError); 5 } 6 7 private void ageTextBox_ValidationError(object sender, ValidationErrorEventArgs e) 8 { 9 MessageBox.Show(e.Error.ErrorContent.ToString,"验证错误"); 10 }
使用工具提示框显示验证信息
<TextBox Name="ageTextBox" ToolTip="{Binding ElementName=ageTextBox, Path=(Validation.Errors)[0].ErrorContent}" > <TextBox.Text> <Binding Path="Age" > <Binding.ValidationRules> <local:NumberRangeRule Min="0" Max="128"/> </Binding.ValidationRules> </Binding> </TextBox.Text> </TextBox>
执行验证的方式: UpdateSourceTrigger="PropertyChanged"
<TextBox Name="ageTextBox" ToolTip="{Binding ElementName=ageTextBox, Path=(Validation.Errors)[0].ErrorContent}" > <TextBox.Text> <Binding Path="Age" UpdateSourceTrigger="PropertyChanged" > <Binding.ValidationRules> <local:NumberRangeRule Min="0" Max="128"/> </Binding.ValidationRules> </Binding> </TextBox.Text> </TextBox>
Binding Path Syntax 绑定路径语法
当您在Binding语句中使用Path=Something时, Something可以采用多种格式,包括以下常
用变体:
Path=Property
Bind to the property of the current object, whether the property is a CLR prop
erty, a dependency property, or an attached property (e.g., Path=Age).
Path=(OwnerType.AttachedProperty)
Bind to an attached dependency property (e.g., Path=(Validation.HasError)).
Path=Property.SubProperty
Bind to a subproperty (or a sub-subproperty, etc.) of the current object (e.g.,
Path=Name.Length).
Path=Property[n]
Bind to an indexer (e.g., Path=Names[0]).
Path=Property/Property
Master-detail binding, described later (e.g., Path=Customers/Orders).
Path=(OwnerType.AttachedProperty)[n].SubProperty
Bind to a mixture of properties, subproperties, and indexers (e.g.,
Path=(Validation.Errors)[0].ErrorContent).