前言: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訪問器來實時寫入新值,這足以顯示出屬性的重要性,因此,熟練運用屬性知識對資料繫結來說非常重要。