zoukankan      html  css  js  c++  java
  • 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就会随着一起更新了。

  • 相关阅读:
    BZOJ_2588_Spoj 10628. Count on a tree_树剖+主席树
    BZOJ_1901_Zju2112 Dynamic Rankings_树状数组+主席树
    单例模式
    JDBC连接数据库查询信息的步骤(提取成配置文件方式)
    JDBC访问数据库查询信息的步骤(硬编码格式)
    大数据
    accp
    递归
    struts2中Action到底是什么,怎么理解
    转发和重定向的区别(简单解释)
  • 原文地址:https://www.cnblogs.com/3xiaolonglong/p/9723542.html
Copyright © 2011-2022 走看看