WPF笔记3:数据绑定

13 篇文章 0 订阅

WPF笔记3:数据绑定

        

         本文摘要:

         1:实体类的绑定;

         2:实体类集合的绑定;

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

 

1:实体类的绑定

         理解WPF数据绑定,首先需要理解接口INotifyCollectionChanged

         场景1UI显示学生信息,当学生姓名发生改变的时候,就需要实时地表现到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。当我们在WPFUI控件中实现绑定的时候,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中修改了studentFirstName或者LastName。则后台代码中的student对象的属性会自动同步变化。

        

2:实体类集合的绑定

         既然对于单个实体类的数据绑定已经实现,那么有没有办法对列表数据,也就是实体类集合进行数据的绑定呢?.NET提供了INotifyCollectionChanged,任何实现了该接口的集合类,都可以用来满足如下场景。

         场景2UI显示学生列表信息。在后台增加或删除学生,或修改列表中单个学生的信息,在前台都能同步显示。同时,前台修改数据,也能同步反应到绑定源中。

         在场景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的所有功能。可以看到,在后台代码中,并没有为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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值