WPF 数据绑定Binding

时间:2023-02-19 20:07:10

什么是数据绑定?

Windows Presentation Foundation (WPF) 数据绑定为应用程序提供了一种简单而一致的方法来显示数据以及与数据交互。

通过数据绑定,您可以对两个不同对象的属性值进行同步。——MSDN

 什么意思呢?先可以这样理解,数据绑定是一种行为,这个行为可以将多个对象的属性显示在UI上,当用户修改了UI上的值之后(当然必须是要看实际情况),对应的属性值也被改变,从而达到数据交互的目的。看一下MSDN上的一幅图(感觉这幅图到处都能看见(偷笑)):

WPF 数据绑定Binding

Binding可以通过XAML语句实现界面与数据的耦合。如果把Binding比作数据的桥梁,那么它的两端分别是Binding的绑定目标和绑定源。数据从哪里来哪里就是源,Binding是架在中间的桥梁,Binding目标是数据要往哪儿去。一般情况下,绑定源是逻辑层的对象,绑定目标是UI层的控件对象,这样,数据就会源源不断通过Binding送达UI层,被UI层展现,也就完成了数据驱动UI的过程。——参考《WPF中的数据绑定

从上图可以看出数据绑定的4个组件,为方便理解,结合例子:将TextBox的内容绑定到Employee对象的Name属性,也就是说把Name的值显示在TextBox上:

  1. 绑定目标对象TextBox
    绑定目标对象可以是所有UIElement对象。为什么?这是自然而然的事情。数据绑定就是为了将数据与UI进行交互,那么绑定的这种行为必然正对所有UIElement对象,例如常见的Button,TextBlock等等。
  2. 目标属性:TextBox的Text属性
  3. 目标属性必须是依赖项属性。为什么呢?在WPF中,只有这样的属性才支持数据绑定,这也就意味着不能绑定字段。不过,在WPF中UIElemnt对象的大部分属性都是依赖属性且大多数依赖属性都是支持数据绑定的。为什么呢?从《WPF依赖属性》中可以知道,只有DependencyObject类型可以定义依赖项属性,而所有UIElement对象都是从DependencyObject派生的。
  4. 绑定源对象:Employee对象

    绑定源的对象可以有哪些呢?WPF支持CLR对象和XML形式的数据:UIElement、任何列表对象、与ADO.NET数据或Web服务关联的CLR对象、包含XML数据的XmlNode.

  5. 绑定源值的path(这个从图中看不出来,但可以想象的出来,^_^):Name

如何绑定?

根据实际应用的情况,绑定目标基本上都是UI对象,我们来看一下绑定数据的各种情况:

1、绑定UI对象
举一个简单例子,选择ComboBox下拉列表中的性别,并显示在TextBlock中。

WPF 数据绑定Binding

xaml:

<StackPanel Orientation="Vertical" VerticalAlignment="Center" HorizontalAlignment="Center">
    <TextBox x:Name="tbk"  Width="100" Height="40" Background="#FFF2F2F2" VerticalAlignment="Top"  TextAlignment="Center" FontSize="24"
                 Text="{Binding ElementName=combo,Path=SelectedItem.SexName}"/>
    <ComboBox x:Name="combo"  Width="100" Height="30" Margin="10" 
                      DisplayMemberPath="SexName" SelectedValuePath="SexId" SelectedIndex="1"/>
</StackPanel>

cs,主要是给ComboBox赋数据源:

    public partial class MainWindow : Window
    {
        List<SexType> _sexCollection;
        public MainWindow()
        {
            InitializeComponent();
            _sexCollection = new List<SexType>()
            {
                new SexType(){SexId=1,SexName=""},
                new SexType(){SexId=2,SexName=""},
                new SexType(){SexId=3,SexName="未知"}
            };
            combo.ItemsSource = _sexCollection;
        }
    }

    public class SexType
    {
        public int SexId { get; set; }
        public string SexName { get; set; }
    }

由上述例子可以看出,绑定目标:TextBox,目标属性:TextBox.Text,绑定源对象:combo,绑定源值的Path:combo.SelectedItem.SexName.个中滋味可以自行感受。

 

2、上面这个例子中comboBox的数据源是在cs中通过”combo.ItemsSource=数据源“来赋值的,那么是否可以通过绑定数据的方式来赋值呢?答案必须是肯定的。

我们知道ComboBox和ListBoxItem都是ItemsControl的派生类,而对于所有的ItemsControl对象都有一个ItemsSource的依赖属性。ItemsSource的类型是IEnumerable,所以集合类型可以成为它绑定的对象。

<ComboBox x:Name="combo"  Width="100" Height="30" Margin="10" 
                      DisplayMemberPath="SexName" SelectedValuePath="SexId" SelectedIndex="1"
                      ItemsSource="{Binding _sexCollection}"/> 

在修改一下cs文件:

    public partial class MainWindow : Window
    {
        public List<SexType> _sexCollection;
        public MainWindow()
        {
            InitializeComponent();
            _sexCollection = new List<SexType>()
            {
                new SexType(){SexId=1,SexName=""},
                new SexType(){SexId=2,SexName=""},
                new SexType(){SexId=3,SexName="未知"}
            };
            //combo.ItemsSource = _sexCollection;
        }
    }

可以看到是没有数据源的,也就是说根本就没有把数据绑到ComboBox上:

WPF 数据绑定Binding

这是为什么呢?依赖属性内的垂直通知功能让UI对相间的绑定可以自己负责同步处理,但是对于.NET集合或对象来讲,就不具备这样的能力了。为了让目标属性与源目标保持同步,源目标必须实现一个叫INotifyPropertyChanged的接口。

 

通常我们只需将集合继承于ObservableCollection类即可。

 

 

 

 

2、绑定集合

3、数据模板

4、为绑定添加规则及转换器

如何绑定不同的源。