• WPF---数据绑定(二)


    一、绑定到非UI元素

    上篇中,我们绑定的数据源均是派生自UIElement的WPF元素。本篇描述的绑定数据源是一个我们自定义的普通的类型。

    注:尽管绑定的数据源可以是任意类型的对象,但Path必须总是指向一个公共属性。

    当绑定一个非UI元素对象时,不能使用Binding.ElementName属性,但可以使用以下属性中的一个:

    Source——该属性是指向源对象的引用,即提供数据的对象;

    RelativeSource——该属性使用RelativeSource对象指定绑定源的相对位置,默认值为null;

    DataContext属性——如果没有使用Source或RelativeSource属性指定一个数据源,WPF会从当前元素开始在元素树中向上查找,

    检查每个元素的DataContext属性,并使用第一个非空的DataContext属性。当然你也可以自己设置DataContext属性。

    下面我们模拟以下场景,左面的lable分别绑定我们自定义的类Person的Age和Name属性,右面我们可以动态的修改person中的Age和Name属性,当属性动态修改的时候,我们观察左面的lable中的文本信息是否发生变化。

    参考代码如下:

    using System;
    using System.ComponentModel;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    
    namespace BindingDemo2
    {
        /// <summary>
        /// Interaction logic for MainWindow.xaml
        /// </summary>
        public partial class MainWindow : Window
        {
            private Person person;
            public Person Person
            {
                get { return person; }
                set { person = value; }
            }
            public MainWindow()
            {
                InitializeComponent();
    
                this.DataContext = this;
    
                person = new Person();
    
                Binding binding = new Binding("Age") { Source = person };
                lbAge.SetBinding(Label.ContentProperty, binding);
    
            }
    
            private void Button_Click(object sender, RoutedEventArgs e)
            {   
                person.Age = Convert.ToInt32(tbAge.Text);
                person.Name = tbName.Text;
            }
        }
        public class Person
        {
            private int _age = 18;
    
            public int Age
            {
                get { return _age; }
                set
                {
                    _age = value;
                }
            }
    
            private string _name = "Mary";
            public string Name
            {
                get { return _name; }
                set
                {
                    _name = value;
                }
            }
            public Person()
            {
                Age = 18;
                Name = "Mary";
            }
    
        }
    
    }
    <Window x:Class="BindingDemo2.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:BindingDemo2"
            mc:Ignorable="d"
            Title="MainWindow" Height="350" Width="525" Name="win">
        <Grid ShowGridLines="True">
            <Grid.ColumnDefinitions>
                <ColumnDefinition/>
                <ColumnDefinition/>
            </Grid.ColumnDefinitions>
            <StackPanel>
                <Label Content="Target"/>
                <Label Content="Name"/>
                <Label Content="{Binding Person.Name}" Height="30" Background="AliceBlue" Name="lbName"/>
                <Label Content="Age"/>
                <Label  Height="30" Background="AliceBlue" Name="lbAge"/>
            </StackPanel>
            <StackPanel Grid.Column="1">
                <Label Content="Source"/>
                <Label Content="Name"/>
                <TextBox Height="30" Background="AliceBlue" Name="tbName" Text="Mary"/>
                <Label Content="Age"/>
                <TextBox Height="30" Background="AliceBlue" Name="tbAge" Text="18"/>
                <Button Content="Set" Click="Button_Click"></Button>
            </StackPanel>
        </Grid>
    </Window>

    运行结果如下:

     从结果可以发现,我们的绑定成功了。但是,当我们在右面修改Name和Age的时候,左面的lable中的文字信息却没有发生改变,这是为什么呢?

    通过调试我们发现,点击Set按钮之后,person对象中的属性的确是改变了,但是由于属性改变没有通知binding,所以界面的UI没有更新。

    为了可以通知binding属性修改了,我们对数据源Person类做如下修改:

       public class Person : INotifyPropertyChanged
        {
            public event PropertyChangedEventHandler PropertyChanged;
            protected void OnPropertyChanged(string propertyName)
            {
                PropertyChangedEventHandler handler = PropertyChanged;
    
                if (handler != null)
                {
                    handler(this, new PropertyChangedEventArgs(propertyName));
                }
            }
            private int _age = 18;
    
            public int Age
            {
                get { return _age; }
                set
                {
                    _age = value;
                    OnPropertyChanged("Age");
                }
            }
    
            private string _name = "Mary";
    
            public string Name
            {
                get { return _name; }
                set
                {
                    _name = value;
                    OnPropertyChanged("Name");
                }
            }
            public Person()
            {
                Age = 18;
                Name = "Mary";
            }
    
        }

    如此一来,当person更新的时候,UI就会随着一起更新了。

  • 相关阅读:
    自制2048小游戏(附源码)
    PyQt5设计思路(长期更新,每写一篇新博客都会更新一次)
    Orthogonal table 实现理论
    Convex Hull 实现理论
    elasticsearch 命令操作
    Springboot
    2018/3/8错题解析
    初始MyBatis
    如何做好微信订阅号
    在路上,三线城市互联网创业记录
  • 原文地址:https://www.cnblogs.com/3xiaolonglong/p/9723542.html
Copyright © 2020-2023  润新知