C#-WPF資料繫結基礎(一)

C#測量小生發表於2021-11-19

前言:WPF資料繫結技術有效的提高了程式的容錯率,可以最大程度的保持程式的健壯性,從而降低程式在使用過程中崩掉的可能性。

接下來,我將分享一下我在寫測量程式過程中所用到的資料繫結方面的知識

首先,我所用到的資料繫結的基本原理

 

 

如上圖所示,我們通過建立一個類,我們給它取名為檢視模型,通過這個類裡面的屬性可以將我們的後臺與介面實時的聯絡起來,以保證資料的實時更新,我們主要通過基類中的屬性來進行資料繫結。

 

在介面設計程式碼中,我們用到Binding屬性來進行資料繫結,程式碼如下所示

 

 

 1 <Window x:Class="GaussProj.AzimuthWindow"
 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:GaussProj"
 7         mc:Ignorable="d"
 8         Title="座標方位角計算" Height="380" Width="500">
 9     <Window.Resources>
10         <Style TargetType="TextBox">
11             <Setter Property="Background" Value="AliceBlue"/>
12             <Setter Property="VerticalAlignment" Value="Center"/>
13         </Style>
14         <Style TargetType="TextBlock">
15             <Setter Property="Background" Value="AliceBlue"/>
16             <Setter Property="VerticalAlignment" Value="Center"/>
17             <Setter Property="HorizontalAlignment" Value="Right"/>
18         </Style>
19     </Window.Resources>
20     <Grid Margin="20">
21         <Grid.RowDefinitions>
22             <RowDefinition Height="40*"/>
23             <RowDefinition Height="40*"/>
24             <RowDefinition Height="50*"/>
25             <RowDefinition Height="30*"/>
26         </Grid.RowDefinitions>
27         <GroupBox Header="起點">
28             <Grid>
29                 <Grid.ColumnDefinitions>
30                     <ColumnDefinition Width="40*"/>
31                     <ColumnDefinition Width="60*"/>
32                     <ColumnDefinition Width="40*"/>
33                     <ColumnDefinition Width="60*"/>
34                     <ColumnDefinition Width="40*"/>
35                     <ColumnDefinition Width="60*"/>
36                 </Grid.ColumnDefinitions>
37                 <TextBlock Text="點名:" Margin="2" Grid.Row="0" Grid.Column="0"/>
38                 <TextBox x:Name="A_Name" Grid.Row="0" Grid.Column="1" Text="{Binding PA.Name}" Background="AliceBlue" Margin="3"/>
39 
40                 <TextBlock Text="X=" Margin="2" Grid.Row="0" Grid.Column="2"/>
41                 <TextBox x:Name="AX_TextBox" Grid.Row="0" Grid.Column="3" Text="{Binding PA.X}" Background="AliceBlue" Margin="3"/>
42                 <TextBlock Text="Y=:" Margin="2" Grid.Row="0" Grid.Column="4"/>
43                 <TextBox x:Name="AY_TextBox" Grid.Row="0" Grid.Column="5" Text="{Binding PA.Y}" Background="AliceBlue" Margin="3"/>
44             </Grid>
45         </GroupBox>
46         
47         <GroupBox Header="方向點" Grid.Row="1">
48             <Grid>
49                 <Grid.ColumnDefinitions>
50                     <ColumnDefinition Width="40*"/>
51                     <ColumnDefinition Width="60*"/>
52                     <ColumnDefinition Width="40*"/>
53                     <ColumnDefinition Width="60*"/>
54                     <ColumnDefinition Width="40*"/>
55                     <ColumnDefinition Width="60*"/>
56                 </Grid.ColumnDefinitions>
57                 <TextBlock Text="點名:" Margin="2" Grid.Row="1" Grid.Column="0"/>
58                 <TextBox  x:Name="B_Name" Grid.Row="1" Grid.Column="1" Text="{Binding PB.Name}" Background="AliceBlue"  Margin="3"/>
59 
60                 <TextBlock Text="X=" Margin="2" Grid.Row="1" Grid.Column="2"/>
61                 <TextBox x:Name="BX_TextBox" Grid.Row="1" Grid.Column="3" Text="{Binding PB.X}" Background="AliceBlue" Margin="3"/>
62 
63                 <TextBlock Text="Y=:" Margin="2" Grid.Row="1" Grid.Column="4"/>
64                 <TextBox x:Name="BY_TextBox" Grid.Row="1" Grid.Column="5" Text="{Binding PB.Y}" Background="AliceBlue" Margin="3"/>
65 
66             </Grid>
67         </GroupBox>
68 
69         <GroupBox Header="計算成果"  Grid.Row="2">
70             <Grid>
71                 <Grid.ColumnDefinitions>
72                     <ColumnDefinition Width="105*"/>
73                     <ColumnDefinition Width="120*"/>
74                 </Grid.ColumnDefinitions>
75                 <Grid.RowDefinitions>
76                     <RowDefinition Height="30*"/>
77                     <RowDefinition Height="30*"/>
78                 </Grid.RowDefinitions>
79                 <TextBlock d:Text="座標方位角:" Name="AZ_Name" Text="{Binding AzName}" Grid.Row="0" Grid.Column="0"  Margin="12"/>
80                 <TextBox x:Name="Az" Grid.Row="0" Grid.Column="1" Text="{Binding AzValue}" Background="AliceBlue" Margin="3"/>
81 
82                 <TextBlock Text="距離:" Grid.Row="1"  Grid.Column="0" Margin="12"/>
83                 <TextBox x:Name="Distance" Grid.Row="1" Grid.Column="1" Text="{Binding Dist}" Background="AliceBlue" Margin="3"/>
84             </Grid>
85         </GroupBox>
86         <StackPanel Orientation="Horizontal" Grid.Row="3" HorizontalAlignment="Center">
87             <Button x:Name="Calculate" Content="計算" BorderThickness="3" BorderBrush="YellowGreen" Width="100" Click="Calculate_Click" Margin="10"/>
88             <Button x:Name="Exit" BorderThickness="3" BorderBrush="YellowGreen" Click="Exit_Click" Width="100" Content="關閉" Margin="10"/>
89         </StackPanel>
90     </Grid>
91 </Window>

 

資料繫結模型類的設計程式碼如下:

  1 {
  2     /// <summary>
  3     ///
  4     /// </summary>
  5     public class AzimuthWindowVM : NotifyPropertyObject
  6     {
  7         //public event PropertyChangedEventHandler PropertyChanged;
  8         //public void RaisePropertyChanged(string propertyName)
  9         //{
 10         //    if (PropertyChanged != null)
 11         //    {
 12         //        PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName));
 13         //    }
 14         //}
 15 
 16         private Point pA = new Point("A",0.0,0.0);
 17         public Point PA
 18         {
 19             get { return pA; }
 20             //set
 21             //{
 22             //    pA = value;
 23             //    RaisePropertyChanged("PA");
 24             //    //if (PropertyChanged != null)
 25             //    //{
 26             //    //    PropertyChanged.Invoke(this, new PropertyChangedEventArgs("AName"));
 27             //    //}
 28             //}
 29         }
 30         //private double xA;
 31 
 32         //public double XA
 33         //{
 34         //    get { return xA; }
 35         //    set
 36         //    {
 37         //        xA = value;
 38         //        RaisePropertyChanged("XA");
 39         //        //if (PropertyChanged != null)
 40         //        //{
 41         //        //    PropertyChanged.Invoke(this, new PropertyChangedEventArgs("XA"));
 42         //        //}
 43         //    }
 44         //}
 45 
 46         //private double yA;
 47         //public double YA
 48         //{
 49         //    get { return yA; }
 50         //    set
 51         //    {
 52         //        yA = value;
 53         //        RaisePropertyChanged("YA");
 54         //        //if (PropertyChanged != null)
 55         //        //{
 56         //        //    PropertyChanged.Invoke(this, new PropertyChangedEventArgs("YA"));
 57         //        //}
 58         //    }
 59         //}
 60 
 61         private Point pB = new Point("B",1.0,1.0);
 62         public Point PB
 63         {
 64             get { return pB; }
 65             //set
 66             //{
 67             //    pB = value;
 68             //    RaisePropertyChanged("PB");
 69             //    //if (PropertyChanged != null)
 70             //    //{
 71             //    //    PropertyChanged.Invoke(this, new PropertyChangedEventArgs("BName"));
 72             //    //}
 73             //}
 74         }
 75 
 76         //private double xB;
 77 
 78         //public double XB
 79         //{
 80         //    get { return xB; }
 81         //    set
 82         //    {
 83         //        xB = value;
 84         //        RaisePropertyChanged("XB");
 85         //        //if (PropertyChanged != null)
 86         //        //{
 87         //        //    PropertyChanged.Invoke(this, new PropertyChangedEventArgs("XB"));
 88         //        //}
 89         //    }
 90         //}
 91 
 92         //public double yB;
 93         //public double YB
 94         //{
 95         //    get { return yB; }
 96         //    set
 97         //    {
 98         //        yB = value;
 99         //        RaisePropertyChanged("YB");
100         //        //if (PropertyChanged != null)
101         //        //{
102         //        //    PropertyChanged.Invoke(this, new PropertyChangedEventArgs("YB"));
103         //        //}
104         //    }
105         //}
106 
107 
108         private string azName = "A001->B004的座標方位角";
109         public string AzName
110         {
111             get { return azName; }
112             set { azName = value; RaisePropertyChanged("AzName"); }
113         }
114 
115         private String azValue;
116         public String AzValue
117         {
118             get { return azValue; }
119             set { azValue = value; RaisePropertyChanged("AzValue"); }
120         }
121         private double dist;
122         public double Dist
123         {
124             get { return dist; }
125             set { dist = value;  RaisePropertyChanged("Dist"); }
126         }
127 
128         public void Caculate()
129         {
130             var ad = FZY.SurMath.AzimuthDistance(PA.X, PA.Y, PB.X, PB.Y);
131             AzValue = FZY.SurMath.RADtoDMSString(ad.az);
132             Dist = ad.d;
133             AzName = $"{PA.Name}->{PB.Name}的座標方位角";
134         }
135     }
136 }

很明顯,這個類是從NotifyPropertyObject類繼承過來的

 1 using System.ComponentModel;
 2 
 3 namespace FZY
 4 {
 5     public class NotifyPropertyObject : INotifyPropertyChanged
 6     {
 7         public event PropertyChangedEventHandler PropertyChanged;
 8         public void RaisePropertyChanged(string propertyName)
 9         {
10             if (PropertyChanged != null)
11             {
12                 PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName));
13             }
14         }
15     }
16 }

在這裡,我們用到了INotifyPropertyChanged介面的一些功能。

總結:WPF資料繫結技術實質用到的就是C#中的屬性的知識,我們通過set訪問器來實時寫入新值,這足以顯示出屬性的重要性,因此,熟練運用屬性知識對資料繫結來說非常重要。

 

相關文章