`

WPF入门教程系列(二) 深入剖析WPF Binding的使用方法

    博客分类:
  • .NET
 
阅读更多

同一个对象(特指System.Windows.DependencyObject的子类)的同一种属性(特指DependencyProperty)只能拥有一个binding

这一点可以通过设置binding对象的方法名得知:

public static BindingExpressionBase SetBinding(

      DependencyObject target,

      DependencyProperty dp,

      BindingBase binding

)

 

方法名是SetBinding而不是AddBinding。如果想要验证一下,也可以在listView1_SelectionChanged事件方法中增加断点,可以监视到。

 

当多次在同一个对象上设置Binding时,其实并不会增加多余的binding,而是将原来的binding替换掉了,这里以textBox_ContactID为例如下图:

 

 

 

另一个相对的概念:同一个Binding可以同时与多个对象的多个属性(或同一对象的多个属性)形成Binding这一点就不做实践验证了,在MSDN上《Data Binding Overview》中有一段“Binding and BindingExpression”就是讲这个道理的。

也许很多读者已经知道或潜意识里有了这种概念,这里只是做一些强调。

改善优化WPF Binding

下面的内容在修正错误的同时,还将对原有的Binding做一些小小的改进。

 

在上一篇Blog中,我曾经提到过这样一个问题,在将数据库中的DataTable对象的DefaultView通过XAML语言BindinglistView1对象的ItemsSource上时总是失败。

 

这里顺便公布一下答案,那就是使用DataContext,不过在动手之前先来梳理一下Binding的一些基本概念及使用方法。

在此之前先来点基础知识,都是MSDN上的内容(不过是E文的),感觉不错所以写下来,供大家阅读:

 

l         典型的Binding具有四个重要组成部分:Binding目标对象binding target object)、目标对象属性target property)、Binding数据源binding source)、Path(用于指明要从数据源中取得的值,就是我们通常写的属性名称)。

 

   例如:想要把一个员工(Employee)的姓名(EmpNameBinding显示到一个TextBoxText属性上。

 

   分析一下其中的4个组成部分:Binding目标对象TextBox(因为它要最终使用这些数据);目标对象属性TextProperty(这里要注意,不是Text属性,而是与Text属性相对应的Dependency Property,通常命名是属性名+Property);

 

   数据源是员工(Employee);PathEmpName。我的经验是:刚开始使用Binding的时候由于还不熟悉,建议在做之前先在心理把这4个部分对号入座一下,等日后就可以熟悉成自然了。

 

l         目标对象属性一定要是Dependency Property。由于只有DependencyObject类及其子类能够定义Dependency Property,因此,Binding目标对象就必须是DependencyObject类及其子类了。另一方面反过来说,UIElementDependencyObject的子类)的大多数属性都有与其对应的Dependency Property,因此,大多数的UIElement属性我们都可以利用其Dependency Property作为目标对象属性从而与数据源建立Binding

 

l        再有一点,建立Binding的数据源不一定要是一个CLR对象,也可以是XML数据、ADO.NET对象及DependencyObject

 

关于为什么binding的对象一定要是DependencyObject,为什么binding对象的属性一定要是dependency property,这个我就不知道了。

在我第一次看到在XAML中设置Binding的语法时,简直是满头雾水。这东西到底怎么回事,简直就没有章法可循,一会儿ElementName,一会儿Source,还有时什么都没有,就一个{Binding },再有就是ModeUpdateSourceTrigger等,简直没有头绪。

 

不过只要打开MSDN,看一下System.Windows.Data.Binding对象,似乎开始有点感觉了,查看Binding对象的属性栏(Properties),你会发现,原来我们在XAML中设置Binding时使用的东西和Binding对象的属性好像都是一一对应的。

 

确实如此,在XAML中设置Binding就是在这只System.Windows.Data.Binding对象,这里先提醒一下大家。

 

WPF可不是就这么一个Binding噢,实时上,从BindingBase继承过来的有三个兄弟,Binding只是最常用而已。

找到了binding的老家,相信大家对{Binding ElementName=ElemName, Path=PropertyName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, …}这样的语法应该清楚了吧。

那么{Binding } {Binding XXXX}这样的语法呢?其实可以就是等于new Binding()new Binding(XXXX),其实可以考虑成是分别使用了Binding的两种构造方法,而XXXX的作用自然也就清晰了。

其实和{Binding Path=XXXX}是等价的,都是设置Path属性的。至于这里的Path属性在我们平常使用时其实是用来设置属性名的地方,为什么不直接叫做是PropertyName之类的名字呢?这个又要留着以后思考了。

当一个数据源与一个UIElement形成Binding后,数据源的改变,如果传递给UIElement的指定属性?

同样,当UIElement中指定属性值改变了,如何才能够通知到数据源?要讨论这个问题,需要按数据源来分类进行讨论。这个分类并不是互斥的之前存在一些交集。

因此,同一种Binding场景可能适用于多种情况。下面的内容是来自MSDN中《Binding Sources Overview》中的内容,由于怕翻译的不好而误导大家,所以分类的名称还是使用英文吧。

Using a CLR Class as the Binding Source Object

在典型的Binding情景中,一个CLR 对象作为数据源,将其中一个属性值Binding到某个UIElement的属性上(以上面显示员工姓名的情景为例。

 

XAML实现<TextBox Text=”{Binding Source=Employee, Path=EmpName}” />)。当数据源属性值变化了,相应让UIElement中对应属性变化。

 

需要实现一个中通知机制,最简单的方法是通过实现INotifyPropertyChanged接口完成此操作。具体实现,可以参考MSDN上的文章《How to: Implement Property Change Notification》。

 

其实就是实现了public event PropertyChangedEventHandler PropertyChanged;”事件,通常的做法是在上面加封装一个”protected void OnPropertyChanged(string name)”函数。在属性的set方法结尾处,调用此函数实现通知的作用。

 

如果不实行此接口,则必须自己实现一套通知系统。为你的类中的每一个想要实现通知机制的属性创建一个PropertyChanged模板。

 

即为你的每一个属性创建一个名为PropertyNameChanged事件,其中PropertyName是与这个事件对应的属性名称。然后在属性发生变化是触发这个事件。(听起来就麻烦,我也懒得去实践验证了)

 

如果以上两种方法都无法实现的话,那么就只好在你认为需要的时候显示的调用UpdateTarget方法来手动更新了。

 

(这种方法没用过,感觉已经失去了Binding的意义了)

Entire Objects Used as a Binding Source

可以理解为将整个对象作为数据源,与上一个题目的区别很小。

 

基本上可以认为是原来Binding实现的是数据源属性与UIElement属性之间的Binding,而这次是直接将一个Object对象与一个UIElement的属性进行Binding了。

 

这种情况可以使用BindingSource属性指明数据源(假设Employee对象与一个ListBox实现banding,用XAML实现<ListBox ItemsSource=”{Binding Employee}” />),或者还可以将DataContext属性设置为EmployeeDataContext属性只有UIElement的一个子类System.Windows.FrameworkElement及其子类才会有)

 

这样,在设置ItemsSource时就可以直接使用”{Binding }”这样的语法了。当然,DataContext属性设置成Employee还是需要使用DataContext=”{Binding Employee}”语句的。

 

有人在这里会嘲笑这一举动实在是啰嗦,事实上,DataContext属性是非常有用的。之所以Binding对象失败而最终不得不使用C#语句进行Binding就是因为没有设置DataContext

 

因为,当我们使用{Binding Source= Employee, Path=”EmpName”}设置属性后,WPF查找Source对象是根据Element Tree逐级向上自己的Parent Element查找的,查找每一Element上的DataContext所指定的内容是否包含这一Source内容,并以第一个匹配到的结果作为最终对象。

 

也就是说,DataContext是按照Element Tree向下继承的,并且决定这WPF在运行时能否找到我们所制定的Source对象。即使我们使用{Binding Path=”EmpName”}的语句也是如此。

 

比较常见的做法是,当我们有大量的Element需要与一个数据源中的众多属性实现Binding时,我们可以直接在一个公共Parent ElementDataContext上设置这一对象(甚至可以是整个windowpage上),这将会极大的加少我们重复的代码量,同时也会是程序更加可读。

当我们需要使用的数据源是一个集合时,如果想要实现改变通知的机制。

 

同样需要实现一个接口INotifyCollectionChanged用来在集合发生改变时发起,用法单个对象是实现INotifyPropertyChanged接口类似。

 

首先是将上以前做的不是很好的那一段代码改成XAML语言实现。

 

TextBox标签中的Text属性与上面listView1中被选定的记录listView1.SelectedItem)中对应属性(例如:ContactID)做Binding

 

实现后如图所示:

<TextBox Text="{Binding ElementName=listView1, Path=SelectedItem.ContactID}" MinWidth="100" />

 

看以来代码有点长,而且,下面的几个TextBox也都存在大量的重复内容,这里就可以考虑使用上面所说的DataContext了。

listView1中被选定的记录listView1.SelectedItem)作为DataContext放在公共Parent Element上,做法如下:

 

<WrapPanel Grid.Row="1" Orientation="Horizontal" DataContext="{Binding ElementName=listView1, Path=SelectedItem}">

然后剩下的代码就可以简化很多了:

<StackPanel Orientation="Horizontal" Margin="5,2,5,2">

    <TextBlock Text="ContactID:" TextAlignment="Center" />

    <TextBox Text="{Binding ContactID}" MinWidth="100" />

</StackPanel>

<StackPanel Orientation="Horizontal" Margin="5,2,5,2">

    <TextBlock Text="FirstName:" TextAlignment="Center" />

    <TextBox Text="{Binding FirstName}" MinWidth="100" />

</StackPanel>

<StackPanel Orientation="Horizontal" Margin="5,2,5,2">

    <TextBlock Text="LastName:" TextAlignment="Center" />

    <TextBox Text="{Binding EmailAddress}" MinWidth="100" />

</StackPanel>

<StackPanel Orientation="Horizontal" Margin="5,2,5,2">

    <TextBlock Text="EmailAddress:" TextAlignment="Center" />

    <TextBox Text="{Binding LastName}" MinWidth="100" />

</StackPanel>

 

原来的SelectionChanged事件处理方法现在已经没有用了,将多余的代码去掉:

 

<ListView Name="listView1" SelectionChanged="listView1_SelectionChanged" MinWidth="280" >

 

后台代码中的对应方法也可以删掉了private void listView1_SelectionChanged(object sender, SelectionChangedEventArgs e)

 

F5 Debug运行一下,结果和原来是完全一样的。

在上一文中无得以选择使用C#实现Binding的部分代码,现在使用XAML语言实现,有几种方案可以选择,通过如下几步实现:

1)      将原先建立给listView1建立Binding那一大串代码删掉,替换成如下代码:

listView1.DataContext = dt.DefaultView;

执行结果如下图所示:

 

 

2)      将其与listView1ItemsSource属性建立Binding,设置每一列的headerDisplayMemberBinding值。

这里由于DataContext的原因,ItemsSource可以写成"{Binding }"的形式而其Children Element也都可以简写成"{Binding ContactID}"这样的形式。

<ListView Name="listView1" MinWidth="280" ItemsSource="{Binding }">

    <ListView.View>

        <GridView x:Name="gridView1">

            <GridView.Columns>

                <GridViewColumn DisplayMemberBinding="{Binding ContactID}" Header="ContactID"></GridViewColumn>

                <GridViewColumn DisplayMemberBinding="{Binding FirstName}" Header="FirstName"></GridViewColumn>

                <GridViewColumn DisplayMemberBinding="{Binding LastName}" Header="LastName"></GridViewColumn>

            </GridView.Columns>

        </GridView>

    </ListView.View>

</ListView>

改造完后,运行结果会发现,效果和原来是一样。效率提高了,代码更加简化。

WPF入门系列教程(深入剖析WPF Binding的使用方法(全文完

分类: WPF技术

分享到:
评论

相关推荐

    wpf入门第二篇 MVVM与binding

    wpf入门第二篇 MVVM与binding的示例代码,详情可以查看博主的这篇博客: https://blog.csdn.net/wf824284257/article/details/88758707

    WPF入门教程+源码

    **WPF(Windows Presentation Foundation)入门教程** WPF是微软.NET Framework的一部分,它是一个用于构建Windows桌面应用程序的强大...通过深入理解并实践这个入门教程,你将能够逐步掌握WPF的核心技术和最佳实践。

    WPF学习入门教程

    **WPF学习入门教程** **一、WPF基础入门** WPF,全称为Windows Presentation Foundation,是.NET Framework 3.0的重要组成部分,专为Windows Vista设计。WPF提供了一个全面的编程模型,允许设计人员和开发人员在...

    WPF 基础视频教程(共50集)-3.只使用代码创建WPF应用程序

    本教程将专注于使用C#编程语言,仅通过代码来创建WPF应用程序。这种方式对开发者来说更加灵活,尤其在自动化或者动态构建UI时更为适用。 在WPF中,我们不使用XAML(Extensible Application Markup Language)文件,...

    wpf binding 的两种方法

    标题和描述提到了两种WPF数据绑定的方法,这里我们将深入探讨这两种方法以及如何与数据库进行连接以显示数据。 **一、属性绑定(Property Binding)** 属性绑定是最常见的数据绑定方式,它直接将控件的属性与数据...

    WPF_MVVM_入门教程

    在本文中,我们将深入探讨WPF(Windows Presentation Foundation)中的MVVM(Model-View-ViewModel)设计模式,以及如何利用这一模式入门WPF开发。MVVM是一种流行的应用程序架构,尤其适用于UI(用户界面)与业务...

    WPF Binding绑定 Command命令基础学习源码

    在WPF(Windows Presentation Foundation)开发中,数据绑定和命令是两个非常重要的概念,它们能够实现界面(View)与业务逻辑(ViewModel)之间的松耦合。让我们深入探讨这两个主题。 **WPF数据绑定(Binding)** ...

    WPF的binding代码实例

    在这个“WPF的binding代码实例”中,我们将深入探讨几个基础的绑定用法,帮助开发者更好地理解和应用这一特性。 1. **基本绑定语法** WPF中的数据绑定通常使用`{Binding}`标记来实现。例如,一个`TextBlock`控件的...

    WPF开发教程- 让你成为WPF高手

    这个教程旨在帮助开发者从零开始学习WPF,通过深入理解其核心概念和技术,提升在Windows应用开发中的专业技能。 **一、WPF基础入门** 1. **.NET Framework与WPF的关系**:WPF是.NET Framework 3.0引入的新一代UI...

    高清版WPF深入浅出.pdf

    全书分为两个主要部分,第一部分主要介绍WPF开发的基础知识,包括XAML语言的基础知识、WPF控件的使用以及用户界面布局的设计方法;第二部分则是讲述作为优秀WPF程序员所应掌握的进阶知识,如依赖对象和数据绑定、...

    WPFMVVM入门教程收集.pdf

    WPF MVVM 入门教程 本文是关于 WPF MVVM 的入门教程,旨在帮助读者了解 WPF 和 MVVM 模式的基本概念和应用。作者认为,学习 WPF 需要了解 C# 的基础知识,并且需要学习 MVVM 模式来更好地使用 WPF。 一、数据绑定...

    WPF Binding

    本资料包围绕“WPF Binding”展开,包含源代码,非常适合初学者深入理解和实践。 ### 1. 数据绑定基础 数据绑定允许WPF控件的属性与应用程序的数据源自动保持同步。这意味着当数据源发生变化时,UI会自动更新;...

    WPF入门实例——WPF目录树实例

    在本文中,我们将深入探讨WPF(Windows Presentation Foundation)中的目录树实现,特别是基于`TreeView`控件的实例。WPF是.NET Framework的一部分,它提供了一种强大的UI设计和开发工具,用于创建丰富的桌面应用...

    WPF入门增-删-改-查

    **WPF入门增删改查**是针对初学者的一个教程,旨在帮助他们快速掌握Windows Presentation Foundation(WPF)框架下的基本数据操作,包括添加、删除、修改和查询数据。WPF是微软.NET Framework的一部分,它提供了丰富...

    WPF入门增删改查

    **WPF入门增删改查**是针对初学者设计的一套教程,旨在帮助新手快速掌握Windows Presentation Foundation(WPF)的基础知识,特别是如何在WPF应用中实现数据的增、删、改、查操作。WPF是.NET Framework的一个重要...

    WPF快速入门教程之绑定Binding

    在WPF(Windows Presentation Foundation)开发中,数据绑定(Binding)是核心概念之一,它使得UI(用户界面)与应用程序的业务逻辑之间实现数据的自动同步。初学者往往会被Binding的复杂性所困扰,但一旦掌握了基本...

    WPF入门源码实例.rar

    在你提供的压缩包“WPF入门源码实例.rar”中,包含三个项目——MyWpf_one、MyWpf_Three、MyWpf_two,这些都是初学者在学习WPF时编写的实例。这些实例将帮助理解WPF的基本概念和核心特性,如XAML语言、控件使用、数据...

    WPF Binding转换与校验

    ### WPF Binding转换与校验 #### 一、概述 WPF(Windows Presentation Foundation)作为Microsoft推出的用于构建桌面应用程序的框架之一,提供了丰富的特性和工具来帮助开发者构建高性能且美观的应用程序。其中,...

    WPF中文教程.rar

    这个WPF中文教程旨在帮助初学者掌握这一强大的UI框架,通过深入理解XAML语法、控件开发、数据绑定以及图形和多媒体处理,提升开发者在创建现代化用户界面的能力。 **XAML 语法** XAML(eXtensible Application ...

    WPF入门-04绑定Binding(附c#代码)

    WPF绑定使得原本需要多行代码实现的功能,现在只需要简单的XAML代码就可以完成之前多行后台代码实现的功能。 WPF绑定可以理解为一种关系,该关系告诉WPF从一个源对象提取一些信息,并将这些信息来设置目标对象的属性...

Global site tag (gtag.js) - Google Analytics