一、何为数据绑定

场景:考虑一个Window上有一个TextBox和一个Slider两个元素,当我们拖动滑动条的时候,会在TextBox中显示当前滑动条的数值;当我们在TextBox中输入一个有效值,滑动条

中的滑块会滑到TextBox中输入的值所对应的位置。

定义:数据绑定可以理解为两个对象之间的一种关联,对象中的某个属性总是保持同步于另个对象的某个属性值。我们可以形象的把绑定比作一个桥梁,它负责同步桥头两侧的物体。

保持同步的数据元素必须是属性,一个叫源属性,一个叫目标属性;

目标属性必须是一个依赖属性。

二、如何绑定元素对象

关于上面滑动条和文本框的绑定,我们可以用以下Xaml代码实现:

<Window x:Class="BindingDemo1.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:BindingDemo1"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid>
<StackPanel>
<TextBox Name="tbx" Text="{Binding Path=Value, ElementName=sldrSlider}" ></TextBox>
<Slider Name="sldrSlider" Minimum="0" Maximum="100"></Slider>
</StackPanel>
</Grid>
</Window>

等价的后台代码实现如下:

using System.Windows;
using System.Windows.Controls;
using System.Windows.Data; namespace BindingDemo1
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
// Binding binding = new Binding() { ElementName = "sldrSlider",Path= new PropertyPath("Value")};
Binding binding = new Binding("Value") { ElementName = "sldrSlider" };
tbx.SetBinding(TextBox.TextProperty, binding);
}
}
}

后台代码主要完成了以下功能:
 1)创建一个binding对象;

2)设置了binding对象的Source和Path值;

3)调用了目标(textbox)的SetBinding方法创建一个binding表达式,它连接了binding对象和目标依赖属性。

三、数据绑定的方向

我们可以通过设置Binding对象的Mode属性来控制数据绑定的方向。

OneWay:数据源改变时,更新目标;

TwoWay:双向更新;

OneWayToSource:目标改变时,更新数据源;

OneTime:只更新目标一次,使用数据源的初值,以后目标不再被更新;

Default:使用目标的默认绑定模式。

四、触发器---更新数据源的时机

仍然考虑上面滑动条和文本框的绑定关系,我们会发现当文本框的数值改变后,滑动条的滑块不会立即改变,而是在文本框失去焦点的时候,才会改变。

这就涉及到当目标属性变化的时候,数据源如何以及何时变化。

关于数据的更新方向和时机,可以参见下图:

当目标依赖属性发生变化,我们可以利用Binding对象的UpdateSourceTrigger属性来控制何时更新数据源,UpdateSourceTrigger属性值包括以下:

注:UpdateSourceTrigger属性值不影响目标的更新方式,它仅仅控制TwoWay模式或OneWayToSource模式的绑定更新源的方式。

而文本框正是使用LostFocus方式从目标向源进行更新的。

如果要完全控制源对象的更新时机,则可以选择UpdateSourceTrigger.Explicit模式。

此时就需要额外编写代码手动触发更新。可以添加一个Apply按钮,并在按钮的Click事件处理程序中调用BindingExpression.UpdateSource方法立即更新数据源。

参考代码以下:

 1 <Window x:Class="BindingDemo1.MainWindow"
2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4 xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
5 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
6 xmlns:local="clr-namespace:BindingDemo1"
7 mc:Ignorable="d"
8 Title="MainWindow" Height="350" Width="525">
9 <Grid>
10 <StackPanel>
11 <TextBox Name="tbx" Text="{Binding Path=Value, ElementName=sldrSlider,UpdateSourceTrigger=Explicit}" ></TextBox>
12 <Slider Name="sldrSlider" Minimum="0" Maximum="100"></Slider>
13 <Button Height="30" Width="100" Content="Apply" Click="Button_Click"></Button>
14 </StackPanel>
15 </Grid>
16 </Window>
 1 using System.Windows;
2 using System.Windows.Controls;
3 using System.Windows.Data;
4
5 namespace BindingDemo1
6 {
7 /// <summary>
8 /// Interaction logic for MainWindow.xaml
9 /// </summary>
10 public partial class MainWindow : Window
11 {
12 public MainWindow()
13 {
14 InitializeComponent();
15 //Binding binding = new Binding() { ElementName = "sldrSlider",Path= new PropertyPath("Value")};
16 //Binding binding = new Binding("Value") { ElementName = "sldrSlider" ,UpdateSourceTrigger=UpdateSourceTrigger.};
17 //tbx.SetBinding(TextBox.TextProperty, binding);
18 }
19
20 private void Button_Click(object sender, RoutedEventArgs e)
21 {
22 //获得应用于文本框上的绑定
23 BindingExpression be = tbx.GetBindingExpression(TextBox.TextProperty);
24 //调用UpdateSource更新源对象
25 be.UpdateSource();
26 }
27 }
28 }

 五、转换器

上面的例子中,当拖动滑动条的时候,文本框中显示的数字会显示好多位小数,现在我们想让在文本框中只显示两位小数,这时候就需要转换器来实现了。

定义:转化器是一个类,用于拦截数据源和目标之间的数据,拦截之后,就可以按照我们的意愿对数据进行操作。

转换器包括单值转换器和多值转换器。单值转换器需要实现IValueConverter接口,多值转换器需要实现IMultiValueConverter接口。

对于上面的需求,我们可以使用单值转换器,参考代码如下:

 1 using System;
2 using System.Globalization;
3 using System.Windows;
4 using System.Windows.Controls;
5 using System.Windows.Data;
6
7 namespace BindingDemo1
8 {
9 /// <summary>
10 /// Interaction logic for MainWindow.xaml
11 /// </summary>
12 public partial class MainWindow : Window
13 {
14 public MainWindow()
15 {
16 InitializeComponent();
17 //Binding binding = new Binding() { ElementName = "sldrSlider",Path= new PropertyPath("Value")};
18 //Binding binding = new Binding("Value") { ElementName = "sldrSlider" ,UpdateSourceTrigger=UpdateSourceTrigger.};
19 //tbx.SetBinding(TextBox.TextProperty, binding);
20 }
21
22 private void Button_Click(object sender, RoutedEventArgs e)
23 {
24 //获得应用于文本框上的绑定
25 BindingExpression be = tbx.GetBindingExpression(TextBox.TextProperty);
26 //调用UpdateSource更新源对象
27 be.UpdateSource();
28 }
29 }
30 public class SliderValue2StringConverter:IValueConverter
31 {
32 public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
33 {
34 double valueFromSource = (double)value;
35 return valueFromSource.ToString("F2");//保留两位小数
36 }
37
38 public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
39 {
40 throw new NotImplementedException("Method ConvertBack not implemented");
41 }
42 }
43 }
 1 <Window x:Class="BindingDemo1.MainWindow"
2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4 xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
5 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
6 xmlns:local="clr-namespace:BindingDemo1"
7 mc:Ignorable="d"
8 Title="MainWindow" Height="350" Width="525">
9 <Window.Resources>
10 <local:SliderValue2StringConverter x:Key="s2vCvt"></local:SliderValue2StringConverter>
11 </Window.Resources>
12 <Grid>
13 <StackPanel>
14 <TextBox Name="tbx" Text="{Binding Path=Value, ElementName=sldrSlider,UpdateSourceTrigger=Explicit,Converter={StaticResource ResourceKey=s2vCvt}}" ></TextBox>
15 <Slider Name="sldrSlider" Minimum="0" Maximum="100"></Slider>
16 <Button Height="30" Width="100" Content="Apply" Click="Button_Click"></Button>
17 </StackPanel>
18 </Grid>
19 </Window>

现在考虑以下场景,我们有一个椭圆,椭圆的颜色是根据RGB三个不同的分量变化的,我们让三个滑动条分别控制RGB三个分量,下面就用多值转换器进行实现。

 1 using System;
2 using System.Globalization;
3 using System.Windows;
4 using System.Windows.Controls;
5 using System.Windows.Data;
6 using System.Windows.Media;
7
8 namespace BindingDemo1
9 {
10 /// <summary>
11 /// Interaction logic for MainWindow.xaml
12 /// </summary>
13 public partial class MainWindow : Window
14 {
15 public MainWindow()
16 {
17 InitializeComponent();
18 //Binding binding = new Binding() { ElementName = "sldrSlider",Path= new PropertyPath("Value")};
19 //Binding binding = new Binding("Value") { ElementName = "sldrSlider" ,UpdateSourceTrigger=UpdateSourceTrigger.};
20 //tbx.SetBinding(TextBox.TextProperty, binding);
21 }
22
23 private void Button_Click(object sender, RoutedEventArgs e)
24 {
25 //获得应用于文本框上的绑定
26 BindingExpression be = tbx.GetBindingExpression(TextBox.TextProperty);
27 //调用UpdateSource更新源对象
28 be.UpdateSource();
29 }
30 }
31 public class SliderValue2StringConverter:IValueConverter
32 {
33 public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
34 {
35 double valueFromSource = (double)value;
36 return valueFromSource.ToString("F2");//保留两位小数
37 }
38
39 public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
40 {
41 throw new NotImplementedException("Method ConvertBack not implemented");
42 }
43 }
44 public class Rgb2ColorConverter : IMultiValueConverter
45 {
46 //正向修改,整合颜色值
47 public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
48 {
49 if (values == null || values.Length < 3)
50 return null;
51 byte r = System.Convert.ToByte(values[0]);
52 byte g = System.Convert.ToByte(values[1]);
53 byte b = System.Convert.ToByte(values[2]);
54 Color myColor = Color.FromRgb(r, g, b);
55 SolidColorBrush myBrush = new SolidColorBrush(myColor);
56 return myBrush;
57 }
58 public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
59 {
60 throw new NotImplementedException("Method ConvertBack not implemented");
61 }
62
63 }
64 }
 1 <Window x:Class="BindingDemo1.MainWindow"
2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4 xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
5 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
6 xmlns:local="clr-namespace:BindingDemo1"
7 mc:Ignorable="d"
8 Title="MainWindow" Height="350" Width="525">
9 <Window.Resources>
10 <local:SliderValue2StringConverter x:Key="s2vCvt"></local:SliderValue2StringConverter>
11 </Window.Resources>
12 <Grid>
13 <Grid.ColumnDefinitions>
14 <ColumnDefinition Width="191*"/>
15 <ColumnDefinition Width="326*"/>
16 </Grid.ColumnDefinitions>
17 <Grid.RowDefinitions>
18 <RowDefinition Height="111*"/>
19 <RowDefinition Height="209*"/>
20 </Grid.RowDefinitions>
21 <StackPanel>
22 <TextBox Name="tbx" Text="{Binding Path=Value, ElementName=sldrSlider,UpdateSourceTrigger=Explicit,Converter={StaticResource ResourceKey=s2vCvt}}" ></TextBox>
23 <Slider Name="sldrSlider" Minimum="0" Maximum="100"></Slider>
24 <Button Height="30" Width="100" Content="Apply" Click="Button_Click"></Button>
25
26 </StackPanel>
27 <StackPanel Grid.Column="1">
28 <StackPanel Orientation="Horizontal">
29 <Label Content="R:"></Label>
30 <Slider Name="sldR" Foreground="Red" Width="300" Minimum="0" Maximum="255" Ticks="1"></Slider>
31 </StackPanel>
32 <StackPanel Orientation="Horizontal">
33 <Label Content="G:"></Label>
34 <Slider Name="sldG" Foreground="Red" Width="300" Minimum="0" Maximum="255" Ticks="1"></Slider>
35 </StackPanel>
36 <StackPanel Orientation="Horizontal">
37 <Label Content="B:"></Label>
38 <Slider x:Name="sldB" Foreground="Red" Width="300" Minimum="0" Maximum="255" Ticks="1"/>
39 </StackPanel>
40 <StackPanel Orientation="Horizontal">
41 <Label Content="O:"></Label>
42 <Slider Name="sldO" Foreground="Red" Width="300" Minimum="0" Maximum="1" Ticks="0.1" Value="0.5"></Slider>
43 </StackPanel>
44
45 </StackPanel>
46 <Ellipse Grid.Row="1" Grid.Column="1" Stroke="Pink">
47 <Ellipse.Resources>
48 <local:Rgb2ColorConverter x:Key="colorCvt"></local:Rgb2ColorConverter>
49 </Ellipse.Resources>
50 <Ellipse.Fill>
51 <MultiBinding Converter="{StaticResource colorCvt}">
52 <Binding ElementName="sldR" Path="Value"></Binding>
53 <Binding ElementName="sldG" Path="Value"></Binding>
54 <Binding ElementName="sldB" Path="Value"></Binding>
55 </MultiBinding>
56 </Ellipse.Fill>
57 <Ellipse.Opacity>
58 <Binding Path="Value" ElementName="sldO" >
59
60 </Binding>
61 </Ellipse.Opacity>
62 </Ellipse>
63 </Grid>
64 </Window>

六、绑定的删除

我们可以使用类BindingOperations中的以下函数来删除绑定

public static void ClearAllBindings(DependencyObject target);
public static void ClearBinding(DependencyObject target, DependencyProperty dp);

WPF---数据绑定(一)的更多相关文章

  1. WPF 数据绑定Binding

    什么是数据绑定? Windows Presentation Foundation (WPF) 数据绑定为应用程序提供了一种简单而一致的方法来显示数据以及与数据交互. 通过数据绑定,您可以对两个不同对象 ...

  2. WPF数据绑定Binding(二)

    WPF数据绑定Binding(二) 1.UI控件直接的数据绑定 UI对象间的绑定,也是最基本的形式,通常是将源对象Source的某个属性值绑定 (拷贝) 到目标对象Destination的某个属性上. ...

  3. WPF——数据绑定(一)什么是数据绑定

    注意:本人初学WPF,文中可能有表达或者技术性问题,欢迎指正!谢谢! 一:什么是数据绑定? “Windows Presentation Foundation (WPF) 数据绑定为应用程序提供了一种简 ...

  4. 剖析WPF数据绑定机制

    引言 WPF框架采取的是MVVM模式,也就是数据驱动UI,UI控件(Controls)被严格地限制在表示层内,不会参与业务逻辑的处理,只是通过数据绑定(Data Binding)简单忠实地表达与之绑定 ...

  5. WPF 10天修炼 第十天- WPF数据绑定

    WPF数据绑定 数据绑定到元素属性是将源对象指定为一个WPF元素,并且源属性是一个依赖属性,依赖属性内置了变更通知.当改变源对象依赖属性值之后,绑定目标可以立即得到更新,开发人员不需要手动编写响应事件 ...

  6. 微软原文翻译:适用于.Net Core的WPF数据绑定概述

    原文链接,大部分是机器翻译,仅做了小部分修改.英.中文对照,看不懂的看英文. Data binding overview in WPF 2019/09/19 Data binding in Windo ...

  7. C#-WPF数据绑定基础(一)

    前言:WPF数据绑定技术有效的提高了程序的容错率,可以最大程度的保持程序的健壮性,从而降低程序在使用过程中崩掉的可能性. 接下来,我将分享一下我在写测量程序过程中所用到的数据绑定方面的知识 首先,我所 ...

  8. C#WPF数据绑定模板化操作四步走

    前言:WPF数据绑定对于WPF应用程序来说尤为重要,本文将讲述使用MVVM模式进行数据绑定的四步走用法: 具体实例代码如下: 以下代码仅供参考,如有问题请在评论区留言,谢谢 1 第一步:声明一个类用来 ...

  9. WPF 数据绑定 1_1 基础知识&绑定到元素属性

    A.数据绑定基础: 数据源对象:WPF将从该对象中提取信息,交由目标对象进行显示. 目标对象:从数据源中提取信息,并赋给该对象的属性. B.绑定到元素属性 最简单的绑定情形则是将一个源对象指定为一个W ...

  10. WPF 数据绑定基础

    纯理论,可能会枯燥. .net 技术群: 199281001 ,欢迎加入. 1.目标对象一定是派生自DependencyObject的对象,并且目标属性必须是依赖属性,否则数据绑定操作将会失   败. ...

随机推荐

  1. Beautifulsoup网页解析——爬取豆瓣排行榜分类接口

    我们在网页爬取的过程中,会通过requests成功的获取到所需要的信息,而且,在返回的网页信息中,也是通过HTML代码的形式进行展示的.HTML代码都是通过固定的标签组合来实现页面信息的展示,所以,最 ...

  2. PLICP

    介绍 PLICP相比较于普通ICP算法,使用点线之间的距离作为度量,最终找到一个最小化该度量的闭式解(解析解). 最优结果以平方的速度收敛.相比较于ICP,IDC,MBICP.PLICP更加准确,且需 ...

  3. Laravel使用artisan快速实现表单的登陆注册

    1. 开发环境 macOS Mojave 10.14.6 XAMPP 5.6.38 Laravel 5.2 2. 在终端,先进入到项目根目录并执行执行命令 php artisan make:auth ...

  4. js学习笔记之排序算法的原理及代码

    冒泡排序 比较任何两个相邻的项,如果第一个比第二个大,则交换它们 重复这样的操作,直到排序完成,具体代码如下: let arr = [67,23,11,89,45,76,56,99] function ...

  5. CSS中content属性的妙用

    前言 本文讲解CSS中使用频率并不高的content属性,通过多个实用的案例,带你由浅入深的掌握content的用法,让代码变得更加简洁.高效. 定义 W3school中这样定义: content 属 ...

  6. WPF DataGrid DataGridTextColumn

    Style设置时,无法绑定到数据,需要这样写 1 <DataGridTextColumn Header="呵呵" Binding="{Binding ID}&quo ...

  7. promise详解 : 实现promise(附实现代码)

    promise then 的特点 : then 函数的返回值是一个 promise, 可以继续调用 then 函数 回调函数 resolve 和 reject 的参数 value /reason, 可 ...

  8. NCB | 定量蛋白质组学揭示细胞外泌体通用标志物Syntenin-1

    外泌体 (exosomes) 是由哺乳动物细胞通过"内吞-融合-外排"等机制,主动向胞外释放的纳米级 (直径40~60 nm) 双层囊泡小体,携带蛋白质.核酸.脂质等多种生物活性分 ...

  9. 密码三次就会锁掉 while 循环

    while 只要给定的条件为真,C 语言中的 while 循环语句会重复执行一个目标语句 一般定义 //return_type function_name( parameter list ) //{ ...

  10. 安装MySQL详细说明

    安装MySQL详细说明 下载后得到zip压缩包 解压到自己的安装目录 添加环境变量 我的电脑->属性->高级->环境变量 选择PATH,在其后面添加:你的mysql安装文件下面的bi ...