WPF快速指导3:数据绑定

简介: WPF快速指导3:数据绑定  本文摘要:1:实体类的绑定;2:实体类集合的绑定及DataTemplate;3:自定义的实体类集合,如ObservableDictionary; 4:Path的语法; 1:实体类的绑定          理解WPF数据绑定,首先需要理解接口INotifyCollectionChanged。

WPF快速指导3:数据绑定 

本文摘要:
1:实体类的绑定;
2:实体类集合的绑定及DataTemplate;
3:自定义的实体类集合,如ObservableDictionary;
4:Path的语法;


1:实体类的绑定

         理解WPF数据绑定,首先需要理解接口INotifyCollectionChanged。
         场景1:UI显示学生信息,当学生姓名发生改变的时候,就需要实时地表现到UI上。在这种情况下,就需要Student这个类实现INotifyCollectionChanged接口。如下:

    public class Student : INotifyPropertyChanged
    {
        string firstName;
        public string FirstName { get { return firstName; } set { firstName = value; Notify("FirstName"); } }
        string lastName;
        public string LastName { get { return lastName; } set { lastName = value; Notify("LastName"); } }

        public Student(string firstName, string lastName)
        {
            this.firstName = firstName;
            this.lastName = lastName;
        }

        void Notify(string propName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propName));
            }
        }

        #region INotifyPropertyChanged Members
        public event PropertyChangedEventHandler PropertyChanged;
        #endregion
    }

         可以看到,实体类Student需要实现的INotifyPropertyChanged 接口成员为:public event PropertyChangedEventHandler PropertyChanged。当我们在WPF的UI控件中实现绑定的时候,UI会自动为PropertyChanged赋值(为UI的控件对象的OnPropertyChanged)。其次,需要在属性SET方法中实现调用委托变量PropertyChanged,即如上代码片段中的Notify。

         设计一个前台界面:

<Window x:Class="WpfApplication1.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Window1" Height="345" Width="490">
    <DockPanel x:Name="dockPanel">
        <TextBlock DockPanel.Dock="Top">
            <TextBlock>firstName:</TextBlock>
            <TextBox Text="{Binding Path=FirstName}" Width="100"></TextBox>
            <TextBlock>lastName:</TextBlock>
            <TextBox Text="{Binding Path=LastName}" Width="100"></TextBox>
        </TextBlock>
        <Button x:Name="btnView" DockPanel.Dock="Bottom" Height="30">view</Button>
    </DockPanel>
</Window>

         此界面对应后台文件:

    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();
            Student student = new Student("firstname1", "lastName1");
            dockPanel.DataContext = student;
            btnView.Click += new RoutedEventHandler(delegate(object sender, RoutedEventArgs e)
                {
                    MessageBox.Show(student.FirstName);
                });
        }
    }

      以上全部代码实现了场景1,同时,我们还会发现,如果在UI中修改了student的FirstName或者LastName。则后台代码中的student对象的属性会自动同步变化。


2:实体类集合的绑定及DataTemplate

         既然对于单个实体类的数据绑定已经实现,那么有没有办法对列表数据,也就是实体类集合进行数据的绑定呢?.NET提供了INotifyCollectionChanged,任何实现了该接口的集合类,都可以用来满足如下场景。
         场景2:UI显示学生列表信息。在后台增加或删除学生,或修改列表中单个学生的信息,在前台都能同步显示。同时,前台修改数据,也能同步反应到绑定源中。
         在场景2的代码中,使用了ObservableCollection集合类,这个类就是实现了INotifyCollectionChanged接口的一个集合类。

         前台代码:

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <DockPanel x:Name="dockPanel">
        <TextBlock DockPanel.Dock="Top">
            <TextBlock VerticalAlignment="Center">FirstName:</TextBlock>
            <TextBox x:Name="tbFirstName" Text="{Binding Path=FirstName}" Width="150"></TextBox>
            <TextBlock VerticalAlignment="Center">LastName:</TextBlock>
            <TextBox x:Name="tbLastName" Text="{Binding Path=LastName}" Width="150"></TextBox>
        </TextBlock>
        <Button DockPanel.Dock="Bottom" x:Name="addButton">Add</Button>
        <ListBox ItemsSource="{Binding}" IsSynchronizedWithCurrentItem="True">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <TextBlock>
                        <TextBlock Text="{Binding Path=FirstName}" Width="150"></TextBlock>
                        <TextBlock Text="{Binding Path=LastName}" Width="150"></TextBlock>
                    </TextBlock>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
    </DockPanel>
</Window>

         对应的后台代码:

    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            ObservableCollection<Student> students = new ObservableCollection<Student>();
            students.Add(new Student("firstName1", "lastName1"));
            students.Add(new Student("firstName2", "lastName2"));
            this.addButton.Click += (object sender, RoutedEventArgs e) =>
                {
                    students.Add(new Student(tbFirstName.Text.Trim(), tbLastName.Text.Trim()));
                };
            dockPanel.DataContext = students;
        }
    }

         以上代码片段,实现了场景2的所有功能。在《快速指导2中》提到的DataTemplate的作用也体现出来了。可以看到,在后台代码中,并没有为ListBox指定任何数据源,为何ListBox仍旧可以自动绑定数据?在WPF中,如果一个控件为绑定数据源,则会自动到父控件中去找,比如,本示例中,ListBox便会自动绑定dockPanel的数据源。而两个TextBox,则是绑定集合类中的实体类的相关属性。其默认绑定的是索引为0的元素。
         ListBox的属性IsSynchronizedWithCurrentItem="True"表示,如果集合类中的实体属性在后台发生变化,则ListBox将会在UI中动态显示变化。      


3:自定义的实体类集合,如ObservableDictionary

         在上文中提到了提供了,任何实现了INotifyCollectionChanged接口的集合类,都可以用来实现场景2。结果我们用到.NET提供的ObservableCollection集合类。在实际的应用中,会常常用到字典集合类,而.NET却没有提供。这就需要我们自己来实现一个ObservableDictionary。以下是该类的下载地址:

         代码下载地址:http://download.csdn.net/source/2110250。


4:Path的语法

     使用 Path 属性可以指定您要绑定到的源值:

  • 在最简单的情况下,Path 属性值是要用于绑定的源对象的属性名,如 Path=PropertyName。

  • 通过类似于 C# 中使用的语法,可以指定属性的子属性。例如,子句 Path=ShoppingCart.Order 设置与对象或属性 ShoppingCart 的 Order 子属性的绑定。

  • 若要绑定到附加属性,应在附加属性周围放置圆括号。例如,若要绑定到附加属性 DockPanel..::.Dock,则语法是 Path=(DockPanel.Dock)。

  • 可以在要应用索引器的属性名后面的方括号内指定属性的索引器。例如,子句 Path=ShoppingCart[0] 将绑定设置为与属性的内部索引处理文本字符串“0”的方式对应的索引。此外,还支持多个索引器。

  • 可以在 Path 子句中混合索引器和子属性;例如,Path=ShoppingCart.ShippingInfo[MailingAddress,Street].

  • 在索引器内部,您可以有多个由逗号 (,) 分隔的索引器参数。可以使用圆括号指定每个参数的类型。例如,您可以有 Path="[(sys:Int32)42,(sys:Int32)24]",其中 sys 映射到 System 命名空间。

  • 如果源为集合视图,则可以用斜杠 (/) 指定当前项。例如,子句 Path=/ 用于设置到视图中当前项的绑定。如果源为集合,则此语法指定默认集合视图的当前项。

  • 可以结合使用属性名和斜杠来遍历作为集合的属性。例如,Path=/Offices/ManagerName 指定源集合的当前项,该源集合包含也作为集合的 Offices 属性。其当前项是一个包含 ManagerName 属性的对象。

  • 也可以使用句点 (.) 路径绑定到当前源。例如,Text=”{Binding}” 等效于 Text=”{Binding Path=.}”。



练习:

用WPF实现如下的功能
   1:有3个员工,每个员工有自己的姓名和年龄等属性;
   2:WPF页面用列表显示3个员工详细信息;
   3:选中列表中的一项,能在页面的下方显示当前选中员工的详细信息,同时这些详细信息又是可修改的,修改完毕后,列表中该员工的信息能动态更新。

Creative Commons License本文基于 Creative Commons Attribution 2.5 China Mainland License发布,欢迎转载,演绎或用于商业目的,但是必须保留本文的署名 http://www.cnblogs.com/luminji(包含链接)。如您有任何疑问或者授权方面的协商,请给我留言。
目录
相关文章
|
3月前
|
C#
通过Demo学WPF—数据绑定(一)
通过Demo学WPF—数据绑定(一)
39 1
|
3月前
|
开发框架 缓存 前端开发
循序渐进介绍基于CommunityToolkit.Mvvm 和HandyControl的WPF应用端开发(11) -- 下拉列表的数据绑定以及自定义系统字典列表控件
循序渐进介绍基于CommunityToolkit.Mvvm 和HandyControl的WPF应用端开发(11) -- 下拉列表的数据绑定以及自定义系统字典列表控件
|
3月前
|
存储 开发框架 .NET
通过Demo学WPF—数据绑定(二)
通过Demo学WPF—数据绑定(二)
41 1
|
3月前
|
安全 C# 数据安全/隐私保护
WPF安全加固全攻略:从数据绑定到网络通信,多维度防范让你的应用固若金汤,抵御各类攻击
【8月更文挑战第31天】安全性是WPF应用程序开发中不可或缺的一部分。本文从技术角度探讨了WPF应用面临的多种安全威胁及防护措施。通过严格验证绑定数据、限制资源加载来源、实施基于角色的权限管理和使用加密技术保障网络通信安全,可有效提升应用安全性,增强用户信任。例如,使用HTML编码防止XSS攻击、检查资源签名确保其可信度、定义安全策略限制文件访问权限,以及采用HTTPS和加密算法保护数据传输。这些措施有助于全面保障WPF应用的安全性。
51 0
|
3月前
|
数据处理 开发者 C#
WPF数据绑定实战:从零开始,带你玩转数据与界面同步,让你的应用程序更上一层楼!
【8月更文挑战第31天】在WPF应用开发中,数据绑定是核心技能之一,它能实现界面元素与数据源的同步更新。本文详细介绍了WPF数据绑定的概念与实现方法,包括属性绑定、元素绑定及路径绑定等技术,并通过示例代码展示了如何创建数据绑定。通过数据绑定,开发者不仅能简化代码、提高可维护性,还能提升用户体验。无论初学者还是有经验的开发者,都能从中受益,更好地掌握WPF数据绑定技巧。
86 0
|
3月前
|
C#
WPF/C#:数据绑定到方法
WPF/C#:数据绑定到方法
43 0
|
C#
WPF QuickStart系列之数据绑定(Data Binding)
原文:WPF QuickStart系列之数据绑定(Data Binding) 这篇博客将展示WPF DataBinding的内容。 首先看一下WPF Data Binding的概览, Binding Source可以是任意的CLR对象,或者XML文件等,Binding Target需要有依赖属性。
1244 0
|
C# 存储
WPF 实现跑马灯效果的Label控件,数据绑定方式实现
原文:WPF 实现跑马灯效果的Label控件,数据绑定方式实现 项目中需要使用数据绑定的方式实现跑马灯效果的Label,故重构了Label控件;具体代码如下 using System; using System.
2394 0
|
C#
WPF Label控件在数据绑定Content属性变化触发TargetUpdated事件简单实现类似TextChanged 事件效果
原文:WPF Label控件在数据绑定Content属性变化触发TargetUpdated事件简单实现类似TextChanged 事件效果   本以为Label也有TextChanged 事件,但在使用的时候却没找到,网友说Label的Content属性改变肯定是使用赋值操作,赋值的时候就可以对其进行相应的操作所以不需TextChanged 事件。
2059 0
|
C# 存储
【值转换器】 WPF中Image数据绑定Icon对象
原文:【值转换器】 WPF中Image数据绑定Icon对象        这是原来的代码:                这里的MenuIcon是string类型,MenuIcon = "/Image/Tux.ico"。
903 0