• 5-1.Binding的方向、数据更新和Path


    5-1.Binding的方向、数据更新和Path

    Binding可以看做是数据源和目标对象之间的桥梁,源为逻辑层的对象,目标对象则是UI层的控件对象。

    基础

    创建数据源对象类

    class Student
    {
        private string name;
        public string Name
        {
            get {return name;}
            set {name = value;}
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    如果想让Name属性通过Binging送达到UI上,则要设置Binging的Path为Nmae。

    不光如此,如果属性值发生变化后,属性要有能力通知Binging,可以在属性的set方法中出发一个PropertyChanged事件,即继承INotifyPropertyChanged接口。当数据源变化后,Binding会自动监听来自这个接口的PropertyChanged事件。

    public class Student:INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        private string name;
        public string Name
        {
            get { return name; }
            set
            {
                name = value;
                if (PropertyChanged!=null)
                {
                    PropertyChanged.Invoke(this, new PropertyChangedEventArgs("Name"));
                }
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    案例:

    <Window x:Class="WpfApp1.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:WpfApp1"
            mc:Ignorable="d"
            Title="MainWindow" Height="240" Width="400">
        <StackPanel>
            <TextBox x:Name="txtBoxName" />
            <Button Content="Add age" Click="Button_Click"/>
        StackPanel>
    Window>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    public partial class MainWindow : Window
    {
        Student stu;
        public MainWindow()
        {
            InitializeComponent();
            stu = new Student();//准备数据源
            //准备Binding
            Binding binding = new Binding();
            binding.Source = stu;
            binding.Path = new PropertyPath("Name");
            //使用Binding连接数据源和目标
            //第二个参数是目标控件的属性,这是个依赖属性,可以通过Binding依赖在其他对象的属性值上
            BindingOperations.SetBinding(this.txtBoxName, TextBox.TextProperty, binding);
    
            //可以直接使用替代以上的
            this.txtBoxName.SetBinding(TextBox.TextProperty, new Binding("Name") { Source = stu = new Student() });
        }
    
        private void Button_Click(object sender, RoutedEventArgs e)
        {
            stu.Name += "k";
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    在这里插入图片描述

    Binding的源和路径

    标记扩展

    <StackPanel>
        <TextBox x:Name="txtBox1" Text="{Binding Path=Value, ElementName=slider1}"/>
        <Slider x:Name="slider1" SmallChange="1"/>
    </StackPanel>
    
    • 1
    • 2
    • 3
    • 4

    一般会疑问,Text的类型是String,为什么给他赋值了一个Binding类型的值,其实可以吧标记扩展想象为一个具有返回值的函数。

    Binding的方向和数据更新时机

    Binding如果数据仅在UI控件上展示,不许修改则是从源到目标的单向通道。Binding还支持从目标到源的单向沟通以及只读一次数据等操作。

    流向

    BindingMode

    • TwoWay
    • OneWay
    • OnTime
    • OneWayToSource
    • Default(根据实际情况自动选择,如TextBox.Text为双向,TextBlock.Text为单向)

    更新时机

    UpdateSourceTrigger

    • PropertyChanged
    • LostFocus
    • Explicit
    • Default

    Binding还具有NotifyOnSourceUpdated和NotifyOnTargetUpdate两个bool类型的属性,true会激发相应的SourceUpdated或者TargetUpdate事件。

    Binding的Path

    Path决定了把源的哪个属性暴露给Binding。

    • Path可以使用多级路径,即一路点下去,如让一个TextBox显示另一个TextBox的文本长度Text="{Binding Path=Text.Length ElementName=textBox1}"
    • Path可以使用索引器。如让一个TextBox显示两一个TextBox文本的第四个字符Text="{Binding Path=Text.[3] ElementName=textBox1}",中间的.可以省略。
    • 当使用一个集合或者DataView作为源时,如果想把默认元素作为Path
    List<string> stringList = new List<string>(){"Tim","Tom","Blog"};
    this.txt1.SetBinding(TextBox.TextProperty,new Binding("/")){Source = stringList};//Tim
    this.txt2.SetBinding(TextBox.TextProperty,new Binding("/Length")){Source = stringList};//3
    this.txt3.SetBinding(TextBox.TextProperty,new Binding("/[2]")){Source = stringList};//m
    
    • 1
    • 2
    • 3
    • 4

    如果属性仍然是集合,可以一路/下去

    class City{ public string Name{set;get;}}
    class Provice {public string Name{set;get;} pulbic List<City> cityList{set;get;}}
    class Country {public string Name{set;get;} pulbic List<Provice> proviceList{set;get;}}
    
    List<Country> CountryList = new List<Country>(){...}
    this.txt1.SetBinding(TextBox.TextProperty,new Binding("/Name")){Source = CountryList};//中国
    this.txt1.SetBinding(TextBox.TextProperty,new Binding("/provice/Name")){Source = CountryList};//四川
    this.txt1.SetBinding(TextBox.TextProperty,new Binding("/proviceList/cityList/Name")){Source = CountryList};//成都
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    没有Path

    如果数据源本身就是数据且不需要Path来指明,如string,则可以将Path设置为“.”或者不写。在XAML中可以不写,但在C#中必须写"."

    Text ="{Binding Path=.,Soruce={StaticResource ResourceKey=myString}}"

    或者Text ="{Binding .,Soruce={StaticResource ResourceKey=myString}}"

    或者Text ="{Binding Soruce={StaticResource ResourceKey=myString}}"

    C#的方式this.txt.SetBinding(TextBlock.TextProperty,new Binding("."){Source=myString})

  • 相关阅读:
    使用iperf3测试远程服务器之间的带宽和延迟
    视觉感知「挑战」天花板,多摄像头环绕方案同比增长近100%
    技术管理进阶——扎心了!老板问我:你们技术部和外包团队有什么区别?
    (免费分享)java基于SSM的进销存管理系统设计与实现
    Spring-IOC
    kubesphere3.4.1不同等级告警发送至不同邮箱
    一:Spring源码解析之prepareRefresh()
    [护网杯 2018]easy_tornado 1(两种解法!)
    【Git】Git常用命令
    OpenStack云计算(十一)——OpenStack网络管理,验证OpenStack网络资源模型,验证来巩固和加深对OpenStack网络资源模型的理解
  • 原文地址:https://blog.csdn.net/weixin_44064908/article/details/127667712