转载

WPF QuickStart系列之数据绑定(Data Binding)

这篇博客将展示WPF DataBinding的内容。

首先看一下WPF Data Binding的概览,

WPF QuickStart系列之数据绑定(Data Binding)

Binding Source可以是任意的CLR对象,或者XML文件等,Binding Target需要有依赖属性。这样便可以进行Data Binding。请看下面的示例,

C#

public partial class MainWindow : Window {  public MainWindow()  {   InitializeComponent();   DataContext = new Person() { Name = "Tom", Age = 25 };  } } public class Person {  public string Name { get; set; }  public int Age { get; set; } } 

XAML:

<Grid>         <StackPanel>             <TextBlock Text="{Binding Name}" Margin="10,5"/>             <TextBlock Text="{Binding Age}" Margin="10,5"/>         </StackPanel>     </Grid>

运行结果: WPF QuickStart系列之数据绑定(Data Binding)

下面通过一些例子来介绍在Data Binding,

1. 我们可以在XAML中,指定Binding Target的ElementName和Path属性来获取Binding Source的数据,例如,

XAML:

<StackPanel>             <Slider x:Name="_slider" Minimum="0" Maximum="100" Value="20"/>             <TextBox Text="{Binding ElementName=_slider,Path=Value}"/>         </StackPanel>

运行结果: WPF QuickStart系列之数据绑定(Data Binding)

上面XAML代码中,将Slider的Value属性Binding到TextBox。

通过上面的Gif图片可以发现,当拖动Slider时,TextBox框中的数值随着Slider的Value改变而改变,当在TextBox中输入数值时,按Tab键失去焦点后,Slider的Value发生了改变。这是因为TextBox的默认Binding Mode为TwoWay,且UpdateSoureTrigger默认为LostFocus。请看下面的BindingMode示意图,

WPF QuickStart系列之数据绑定(Data Binding)

图示中有种Binding Mode,

OneWay,数据流向是从Source到Target;

TwoWay,数据可以从Source到Target,也可以从Target到Source,

OneWayToSource与OneWay相反,

OneTime,表示数据绑定发生后,数据源无论如何改变,Target中绑定的值都不会发生改变。

下面我们通过例子来演示这4种绑定

XAML:

<Grid>  <Grid.RowDefinitions>   <RowDefinition Height="Auto"/>   <RowDefinition Height="Auto"/>   <RowDefinition Height="Auto"/>   <RowDefinition Height="Auto"/>  </Grid.RowDefinitions>  <!--OneWay Binding-->  <StackPanel>   <TextBlock Text="Binding Mode: OneWay"/>   <Slider x:Name="_slider" Minimum="0" Maximum="100" Value="20"/>   <TextBox Text="{Binding ElementName=_slider,Path=Value,Mode=OneWay}"/>  </StackPanel>  <!--OneTime Binding-->  <StackPanel Grid.Row="1" Margin="0,20">   <TextBlock Text="Binding Mode: OneTime"/>   <Slider x:Name="_slider1" Minimum="0" Maximum="100" Value="20"/>   <TextBox Text="{Binding ElementName=_slider1,Path=Value,Mode=OneTime}"/>  </StackPanel>  <!--OneWayToSource Binding-->  <!--将TextBox的FontSize默认值为12-->  <StackPanel Grid.Row="2">   <TextBlock Text="Binding Mode: OneWayToSource"/>   <Slider x:Name="_slider2" Minimum="0" Maximum="100" Value="20"/>   <TextBox FontSize="{Binding ElementName=_slider2,Path=Value, Mode=OneWayToSource}"       Text="{Binding RelativeSource={RelativeSource Self},Path=FontSize}"/>  </StackPanel>  <!--TwoWay Binding-->  <StackPanel Grid.Row="3" Margin="0,20">   <TextBlock Text="Binding Mode: TwoWay"/>   <Slider x:Name="_slider3" Minimum="0" Maximum="100" Value="20"/>   <TextBox Text="{Binding ElementName=_slider3,Path=Value,Mode=TwoWay}"/>  </StackPanel> </Grid> 

运行结果: WPF QuickStart系列之数据绑定(Data Binding)

在项目开发中根据实际需要选择不同的Binding Mode,如果某些数据只在程序启动时显示,后面对数据进行修改了,不需要更新,可以选择OneTime Mode;如果对数据进行实时展示,可以选择OneWay Mode;如果需要将数据的修改同步,那么我们选择TwoWay Mode。合适的绑定模式可以最优化程序的性能。

接下来看UpdateSourceTrigger,UpdateSourceTrigger有下面几种取值,

1. LostFocus, 例如TextBox失去焦点后更新Source;

2. PropertyChanged,例如当在TextBox中输入时,Source便同步更新;

3. Explict,需要显示的调用 UpdateSource 方法;

下面我们看Binding中另一个概念Converter;看这样一个例子,有一个文本框显示当前温度,如果温度大于35,则将文本框的前景色设置为红色,如果温度小于0,则显示为蓝色;

XAML:

<Window.Resources>  <local:TemperatureToBrushCoverter Hot="35" Cold="0" x:Key="TemperatureToBrushCoverter"/> </Window.Resources> <Grid>  <TextBox Text="30" Width="200" Height="25"      Foreground="{Binding Path=Text,RelativeSource={RelativeSource Self},      Converter={StaticResource TemperatureToBrushCoverter}}"/> </Grid> 

C#:

[ValueConversion(typeof(double),typeof(Brush))] public class TemperatureToBrushCoverter : IValueConverter {  public double Hot { get; set; }  public double Cold { get; set; }  public TemperatureToBrushCoverter()  {  }  public TemperatureToBrushCoverter(double hot,double cold)   :this()  {   Hot = hot;   Cold = cold;  }  public object Convert(object value, Type targetType, object parameter, CultureInfo culture)  {   double temp;   Brush brush = Brushes.Black;   if(Double.TryParse((string)value,out temp))   {    if(temp > Hot)    {     brush = Brushes.Red;    }    else if(temp < Cold)    {     brush = Brushes.Blue;    }   }   return brush;  }  public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)  {   throw new NotImplementedException();  } } 

运行结果:

WPF QuickStart系列之数据绑定(Data Binding)

注意要在XAML中引用Converter。

最后我们看一下DataBinding中的数据验证;来看这样一个例子,将Person对象的Age绑定到一个TextBox上,并可以对Age进行修改,年龄是一个有实际意义的值,如果Age小于0或者大于120,我们均认为其为非法值,给出相应提示。请看下面的代码:

XAML:

<Grid>  <TextBox Width="200" Height="25">   <TextBox.Text>    <Binding Path="Age" UpdateSourceTrigger="PropertyChanged">     <Binding.ValidationRules>      <local:AgeValidationRule ValidationStep="RawProposedValue"/>     </Binding.ValidationRules>    </Binding>   </TextBox.Text>   <!--Error Template-->   <Validation.ErrorTemplate>    <ControlTemplate>     <StackPanel>      <AdornedElementPlaceholder/>      <TextBlock Text="{Binding [0].ErrorContent}" Foreground="Red"/>     </StackPanel>    </ControlTemplate>   </Validation.ErrorTemplate>  </TextBox> </Grid> 

C#:

public partial class MainWindow : Window {  public MainWindow()  {   InitializeComponent();   DataContext = new Person() { Age = 25};  } } public class Person {  public int Age { get; set; } } public class AgeValidationRule : ValidationRule {  public override ValidationResult Validate(object value, CultureInfo cultureInfo)  {   int age;   if(int.TryParse((string)value,out age))   {    if(age< 0 || age > 120)    {     return new ValidationResult(false, "This is invalide age.");    }    else    {     return new ValidationResult(true, null);    }   }   return new ValidationResult(false, "Please input valid age.");  } } 

运行结果:

WPF QuickStart系列之数据绑定(Data Binding)

这篇博客的内容就到这里了,但是WPF中Data Binding的内容远不止这些,会在后面的博客中展现。

感谢您的阅读!代码点击 这里 下载。

正文到此结束
Loading...