WPF之数据绑定Data Binding

一般情况下,应用程序会有三层结构:数据存储层,数据处理层(业务逻辑层),数据展示层(UI界面)。

WPF是“数据驱动UI”。

  • Binding实现(通过纯C#代码)

  Binding分为source和target,即源和目标。

  如何通过Binging实现UI元素和代码对象的连接。

  首先绑定源对象要实现INotifyPropertyChanged接口,该接口引用自System.ComponentModel命名空间,所有使用前要引用该命名空间。该接口有一个PropertyChanged事件,可以帮助自动监听源对象的属性变化。

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 using System.Windows;
 7 using System.Windows.Controls;
 8 using System.Windows.Data;
 9 using System.Windows.Documents;
10 using System.Windows.Input;
11 using System.Windows.Media;
12 using System.Windows.Media.Imaging;
13 using System.Windows.Navigation;
14 using System.Windows.Shapes;
15 using System.ComponentModel;
16    class Student:INotifyPropertyChanged
17     {
18         public event PropertyChangedEventHandler PropertyChanged;
19         private string name;
20 
21         public string Name
22         {
23             get { return name; }
24             set {
25                 name = value;
26                 if(this.PropertyChanged!=null)
27                 {
28                     this.PropertyChanged.Invoke(this, new PropertyChangedEventArgs("Name"));
29                 }
30             }
31         }
32 
33 
34     }

如上代码所示,在绑定了接口以后,当Name属性的值发生变化时,就会自动通知,然后刷新UI元素进行更新。

当然还没有结束,我们现在需要添加界面。然后在后台代码中设置Binding

 其实在textBox元素中已经为我们封装好了这些,即SetBinding方法。

所以可以改写如下:

  • 标记扩展进行Data Binding
  • 控制Binding数据流向的是Mode属性,而控制数据更新的是UpdateSourceTrigger属性
  • 没有Path的Binding

  有时候,Binding源本身就是数据,比如字符串,或者int类型,他们的实例本身就是数据,而不需要通过属性来提供访问,那么在指定path时可以通过一个.来代替,或者直接不写path,在XAML代码里可以省略不写,在C#代码中必须显式写.来表示path指向实例本身。

  • 为Binding指定源的几种方法

 

  •  Binding过程中可以没有path,那么可不可以没有source,当然可以,可以通过添加DataContext来隐式表达source。
  • 使用集合对象作为列表控件的ItemsSource
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 using System.Windows;
 7 using System.Windows.Controls;
 8 using System.Windows.Data;
 9 using System.Windows.Documents;
10 using System.Windows.Input;
11 using System.Windows.Media;
12 using System.Windows.Media.Imaging;
13 using System.Windows.Navigation;
14 using System.Windows.Shapes;
15 using System.ComponentModel;
16 
17 namespace WpfApp7
18 {
19     /// <summary>
20     /// MainWindow.xaml 的交互逻辑
21     /// </summary>
22     public partial class MainWindow : Window
23     {
24         public MainWindow()
25         {
26             InitializeComponent();
27 
28             //准备数据源
29             List<Student> stuList = new List<Student>()
30             {
31                 new Student(){Id=0,Name="Tim",Age=29},
32                 new Student(){Id=1,Name="Tom",Age=28},
33                 new Student(){Id=2,Name="Kyle",Age=27},
34                 new Student(){Id=3,Name="Tony",Age=26},
35                 new Student(){Id=4,Name="Vina",Age=25},
36             };
37             //为listBox设置Binding
38             this.listBoxStudents.ItemsSource = stuList;
39             this.listBoxStudents.DisplayMemberPath = "Name";
40             //为TextBox设置Binding
41             Binding binding = new Binding("SelectedItem.Id") { Source = this.listBoxStudents };
42             this.textBoxId.SetBinding(TextBox.TextProperty, binding);
43         }
44     }
45 
46     class Student
47     {
48         public int Id { get; set; }
49         public string Name { get; set; }
50         public int Age { get; set; }
51 
52     }
53 
54 }

界面代码如下:

<Window x:Class="WpfApp7.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:WpfApp7"
        mc:Ignorable="d"
        Title="Binding Source" Height="240" Width="300">
    <StackPanel x:Name="stackPanel1" Background="LightBlue">
        <TextBlock Text="Student ID" FontWeight="Bold" Margin="5"/>
        <TextBox x:Name="textBoxId" Margin="5"/>
        <TextBlock Text="Student List" FontWeight="Bold" Margin="5"/>
        <ListBox x:Name="listBoxStudents" Height="110" Margin="5"/>

    </StackPanel>
</Window>
  • 使用ObjectDataProvider对象作为Binding的Source

现在有一个Calculator的类,他具有加减乘除的方法:

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 using System.Windows;
 7 using System.Windows.Controls;
 8 using System.Windows.Data;
 9 using System.Windows.Documents;
10 using System.Windows.Input;
11 using System.Windows.Media;
12 using System.Windows.Media.Imaging;
13 using System.Windows.Navigation;
14 using System.Windows.Shapes;
15 
16 namespace ObjectDateProvider
17 {
18     /// <summary>
19     /// MainWindow.xaml 的交互逻辑
20     /// </summary>
21     public partial class MainWindow : Window
22     {
23         public MainWindow()
24         {
25             InitializeComponent();
26             this.SetBinding();
27         }
28 
29 
30         private void SetBinding()
31         {
32             //创建并配置ObjectDataProvider对象
33             ObjectDataProvider odp = new ObjectDataProvider
34             {
35                 ObjectInstance = new Calculator(),
36                 MethodName = "Add"
37             };
38             odp.MethodParameters.Add("0");
39             odp.MethodParameters.Add("0");
40             //以ObjectDataProvider对象为Source创建Binding
41             Binding bindingToArg1 = new Binding("MethodParameters[0]")
42             {
43                 Source = odp,
44                 BindsDirectlyToSource = true,
45                 UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged
46             };
47             Binding bindingToArg2 = new Binding("MethodParameters[1]")
48             {
49                 Source = odp,
50                 BindsDirectlyToSource = true,
51                 UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged
52             };
53 
54             Binding bindingToResult = new Binding(".") { Source = odp };
55 
56             //将Binding关联到UI元素上
57             this.textBoxArg1.SetBinding(TextBox.TextProperty, bindingToArg1);
58             this.textBoxArg2.SetBinding(TextBox.TextProperty, bindingToArg2);
59             this.textBoxResult.SetBinding(TextBox.TextProperty, bindingToResult);
60         }
61     }
62 
63     class Calculator
64     {
65         public string Add(string arg1,string arg2)
66         {
67             double x = 0;
68             double y = 0;
69             double z = 0;   
70             if(double.TryParse(arg1,out x)&&double.TryParse(arg2,out y))
71             {
72                 z = x + y;
73                 return z.ToString();
74             }
75             return "Input Error";
76         }
77     }
78 }

界面代码如下:

 1 <Window x:Class="ObjectDateProvider.MainWindow"
 2         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 3         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 4         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
 5         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
 6         xmlns:local="clr-namespace:ObjectDateProvider"
 7         mc:Ignorable="d"
 8         Title="MainWindow" Height="135" Width="300">
 9     <StackPanel Background="LightBlue">
10         <TextBox x:Name="textBoxArg1" Margin="5"/>
11         <TextBox x:Name="textBoxArg2" Margin="5"/>
12         <TextBox x:Name="textBoxResult" Margin="5"/>
13         
14     </StackPanel>
15 </Window>
界面代码
  • 使用Binding的RelativeSource
  1. Binding对数据的转换与校验

  Binding用于数据有效性检验的是ValidationRules属性,用于数据类型转换关卡的是Converter属性。

  

猜你喜欢

转载自www.cnblogs.com/jackchenor/p/12957180.html