Binding的Source

前言

Binding的源就是数据的来源,这个Source可以是多种不同的数据,比如集合、单个系统自带对象,自定类的对象等,下面做分别介绍。

1、clr自带类型对象

string 类型的对象作为Source

<Window x:Class="控件作为Binding的源.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:控件作为Binding的源" 
        xmlns:sys="clr-namespace:System;assembly=mscorlib"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <StackPanel>
        <TextBox x:Name="tbx_Target1"   Height="100" Background="Green"  />
    </StackPanel>
</Window>

由于string类型的对象没有属性,所以没有Path,使用"."代替,Source 就是String类型的对象str,下面的代码就是将字符串str的值”123“作为binding的源更新给tbx_Target1的Text属性。

  public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            string str = "123";
           tbx_Target1.SetBinding(TextBox.TextProperty, new Binding(".") { Source = str });
        }
    }

运行后结果如下图:
在这里插入图片描述

2、用户自定义类型对象

<Window x:Class="控件作为Binding的源.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:控件作为Binding的源" 
        xmlns:sys="clr-namespace:System;assembly=mscorlib"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <StackPanel>
        <TextBox x:Name="tbx_Target1"   Height="100" Background="Green"  />
    </StackPanel>
</Window>

自定义一个类Person,如下:

 class Person
    {
        public Person(string name)
        {
            this.Name = name;
        }
        public string Name { get; set; }
    }

下面的代码中将Person类的对象person作为binding的Source,将Name属性作为Binding的Path,所以最终tbx_Target1的Text属性的值就是person对象的Name属性也就是”小明“。

 public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();


            Person person = new Person("小明");
           tbx_Target1.SetBinding(TextBox.TextProperty, new Binding("Name") { Source = person });
        }
    }

运行后结果如下图:
在这里插入图片描述

3、通过ElementName指定Source

由于在C#代码中可以直接将对象作为Binding的Source,但是在xaml中不可以,所以要通过对象的Name属性来找到对象,这里的ElementName对应的就是对象的Name属性。
下面的xaml代码中ElementName就是tbx_Source对象的Name属性,由于binding的Path就是Text属性,所以将tbx_Source的Text属性直接赋值给tbx_Target1的Text属性。

<Window x:Class="控件作为Binding的源.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:控件作为Binding的源" 
        xmlns:sys="clr-namespace:System;assembly=mscorlib"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <StackPanel>
        <TextBox x:Name="tbx_Source" Text="123"  Height="100" Background="Green"  />
        <TextBox x:Name="tbx_Target1" Text="{Binding Path=Text,ElementName=tbx_Source}"  Height="100" Background="Green"  />
    </StackPanel>
</Window>

在这里插入图片描述

4、只有Path没有Source

下面的代码中tbx_Target1只是指定了Binding的Path=Name属性,但是binding的源到底是哪个没有指定,在xaml代码中,如果不指定Binding的源,那么默认就从当前对象的DataContext属性寻找Path,并且每个控件对象都有一个DataContext属性,如果从当前控件的DataContext属性中没有找到Path,那么接着从当前控件的父控件中寻找DataContext属性,一直找到控件的最顶层,如果还是没有那么就相当于没找到,由于StackPanel是tbx_Target1的父控件,并且StackPanel的DataContext 属性是一个Person类的对象,该对象有Name属性,所以可以作为Binding的Path。

<Window x:Class="控件作为Binding的源.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:控件作为Binding的源" 
        xmlns:sys="clr-namespace:System;assembly=mscorlib"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <StackPanel>
        <StackPanel.DataContext >
            <local:Person Name="小王"/>
        </StackPanel.DataContext>
        <TextBox x:Name="tbx_Target1" Text="{Binding Path=Name}"  Height="100" Background="Green"  />
    </StackPanel>
</Window>
   public  class Person
    {
     
        public string Name { get; set; }
    }

运行结果如下:
Person类的对象中的Name属性是”小王“。
在这里插入图片描述

5、没有Path也没有Source

下面的代码中,tbx_Target1使用”Path=.“代表没有Path,同时也没有指定Source,没有指定Path的场景一般是源没有属性,直接将源更新给目标的情况,所以下面的代码中直接将字符串”我是测试文本“更新给目标tbx_Target1的Text属性。

<Window x:Class="控件作为Binding的源.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:控件作为Binding的源" 
        xmlns:sys="clr-namespace:System;assembly=mscorlib"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <StackPanel>
        <StackPanel.DataContext >
            <sys:String >我是测试文本</sys:String >
        </StackPanel.DataContext>
        <TextBox x:Name="tbx_Target1" Text="{Binding Path=.}"  Height="100" Background="Green"  />
    </StackPanel>
</Window>

6、集合对象作为列表控件的ItemSource

下面的xaml代码中有一个ListBox列表控件list_Target1,一个Button按钮btn_test,我想要实现的效果是声明一个集合对象,这个对象的元素显示到list_Target1中,并且点击按钮btn_test,list_Target1的值发生变化。

<Window x:Class="控件作为Binding的源.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:控件作为Binding的源" 
        xmlns:sys="clr-namespace:System;assembly=mscorlib"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <StackPanel>
        <StackPanel.DataContext >
            <sys:String >我是测试文本</sys:String >
        </StackPanel.DataContext>
        <ListBox x:Name="list_Target1"  Height="100" Background="Green" >
        </ListBox>
        <Button x:Name="btn_test" Height="20" Background="Red"  Click="btn_test_Click"  />
    </StackPanel>
</Window>

定义一个类Person,并且实现INotifyPropertyChanged接口,这样当这个集合属性发生改变的时候,binding的目标也能更新。

 public  class Person : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        public string Name { get; set; }

        private int age;
        public int Age
        {
            get
            {
                return age;
            }
            set
            {
                age = value;
                if (this.PropertyChanged != null)
                {
                    PropertyChanged.Invoke(this, new PropertyChangedEventArgs("Age"));
                }

            }
        }
    }

下面的代码中,首先声明一个 ObservableCollection 集合对象,这里不使用List集合的原因是ObservableCollection能将集合的变化通知给列表控件,但是List不能。集合中放入三个Person对象。然后使用 list_Target1 .ItemsSource = people;将person对象作为list_Target1 的源,接着 通过 list_Target1.DisplayMemberPath = “Age”;来指定列表控件绑定的是Person对象的哪个属性,这里是Age属性,最后在button按钮事件中改变集合中第一个元素的Age的值,每次点击都将Age+1。

  public partial class MainWindow : Window
    {
        ObservableCollection<Person> people = new ObservableCollection<Person>();
        public MainWindow()
        {
            InitializeComponent();
            Person person1 = new Person();
            person1.Name = "小明";
            person1.Age = 10;

            Person person2 = new Person();
            person2.Name = "小王";
            person2.Age = 20;

            Person person3 = new Person();
            person3.Name = "小李";
            person3.Age = 30;

            people.Add(person1);
            people.Add(person2);
            people.Add(person3);

            list_Target1 .ItemsSource = people;
            list_Target1.DisplayMemberPath = "Age";
        }

        private void btn_test_Click(object sender, RoutedEventArgs e)
        {
            people[0].Age ++;
        }
    }

运行结果如下:
集合中的所有Age属性都显示到了列表控件中
在这里插入图片描述
当点击一次下方红色按钮以后,列表中第一个元素值+1。
在这里插入图片描述

这里如果将 ObservableCollection people = new ObservableCollection();改成 List people = new List();如果只是改变集合某个元素的值那么都有效,这是因为Person类实现了INotifyPropertyChanged接口,但是如果将按钮中的值从 people[0].Age ++;改成 如下代码:

private void btn_test_Click(object sender, RoutedEventArgs e)
        {
            Person person= new Person();
            person.Name = "小陈";
            person.Age = 15;
            people.Add(person);
        }

相当于现在是改变集合元素的数量,你会发现使用ObservableCollection people = new ObservableCollection();时,改变集合元素,列表控件也改变;但是使用List people = new List();时,改变集合元素,列表控件不会发生改变,这是因为ObservableCollection 实现了INotifyCollectionChanged接口,综上所属最好使用ObservableCollection而不是List。

7、DataTable对象作为列表控件的ItemSource

7.1、DataTable某一列显示到ListBox控件中

下面的xaml代码中有一个ListBox控件list_Target1,

<Window x:Class="控件作为Binding的源.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:控件作为Binding的源" 
        xmlns:sys="clr-namespace:System;assembly=mscorlib"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <StackPanel>
        <ListBox x:Name="list_Target1"  Height="100" Background="Green" >
        </ListBox>
    </StackPanel>
</Window>

下面的代码中,首先声明了一个DataTable 对象dt,然后这个表格有两个列Name和Age,然后我们需要在list_Target1 这个列表控件中显示dt的Name列,然后只需要设置 list_Target1 .ItemsSource = dt.DefaultView ;然后设置列表需要展示databel哪一列 list_Target1.DisplayMemberPath = “Name”;。

  public MainWindow()
        {
            InitializeComponent();
            DataTable dt = new DataTable();
            dt.Columns.Add("Name",typeof (string ));
            dt.Columns.Add("Age", typeof(int));

            dt.Rows.Add("小明", 10);
            dt.Rows.Add("小王", 20);
            dt.Rows.Add("小宋", 30);
            dt.Rows.Add("小李", 40);
            dt.Rows.Add("小程", 50);

            list_Target1 .ItemsSource = dt.DefaultView ;
            list_Target1.DisplayMemberPath = "Name";
        }

运行结果如下:
可以看到dt的Name列全部显示到了list_Target1中。
在这里插入图片描述

7.2、DataTable所有列显示到ListView控件中

下面的xaml代码中,ListView 用于展示Datatable中的数据,并且ListView定义了两个列,“姓名”、“年龄”,DisplayMemberBinding用于执行绑定的列名。

<Window x:Class="控件作为Binding的源.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:控件作为Binding的源" 
        xmlns:sys="clr-namespace:System;assembly=mscorlib"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <StackPanel>
        <ListView x:Name="listview_test" >
            <ListView.View>
                <GridView>
                    <GridViewColumn  Header="姓名" DisplayMemberBinding="{Binding Name}"/>
                    <GridViewColumn  Header="年龄" DisplayMemberBinding="{Binding Age}"/>
                </GridView>
            </ListView.View>
        </ListView>
    </StackPanel>
</Window>

下面的代码中首先定义了一个DataTable 对象dt,并且定义了两个列"Name"、“Age”,最后通过设置listview_test.ItemsSource = dt.DefaultView ;来将dt的数据作为listview_test的源。

  public MainWindow()
        {
            InitializeComponent();
            DataTable dt = new DataTable();
            dt.Columns.Add("Name",typeof (string ));
            dt.Columns.Add("Age", typeof(int));

            dt.Rows.Add("小明", 10);
            dt.Rows.Add("小王", 20);
            dt.Rows.Add("小宋", 30);
            dt.Rows.Add("小李", 40);
            dt.Rows.Add("小程", 50);

            listview_test.ItemsSource = dt.DefaultView ;
        }

运行效果如下:
在这里插入图片描述

马工撰写的年入30万+C#上位机项目实战必备教程(点击下方链接即可访问文章目录)

1、《C#串口通信从入门到精通》
2、《C#与PLC通信从入门到精通 》
3、《C# Modbus通信从入门到精通》
4、《C#Socket通信从入门到精通 》
5、《C# MES通信从入门到精通》
6、《winform控件从入门到精通》
7、《C#操作MySql数据库从入门到精通》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

上位机马工

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值