原文: WPF QuickStart系列之資料綁定(Data Binding)
這篇部落格将展示WPF DataBinding的内容。
首先看一下WPF Data Binding的概覽,
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIn5GcuUTO2kzNxIGMlJTO2EWZzMzM2M2YxkDZjVmZ1MjN0YGOfdWbp9CXt92Yu4GZjlGbh5SZslmZxl3Lc9CX6MHc0RHaiojIsJye.png)
Binding Source可以是任意的CLR對象,或者XML檔案等,Binding Target需要有依賴屬性。這樣便可以進行Data Binding。請看下面的示例,
C#
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new Person() { Name = "Tom", Age = 25 };
}
}
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
XAML:
<Grid>
<StackPanel>
<TextBlock Text="{Binding Name}" Margin="10,5"/>
<TextBlock Text="{Binding Age}" Margin="10,5"/>
</StackPanel>
</Grid>
運作結果:
下面通過一些例子來介紹在Data Binding,
1. 我們可以在XAML中,指定Binding Target的ElementName和Path屬性來擷取Binding Source的資料,例如,
<StackPanel>
<Slider x:Name="_slider" Minimum="0" Maximum="100" Value="20"/>
<TextBox Text="{Binding ElementName=_slider,Path=Value}"/>
</StackPanel>
上面XAML代碼中,将Slider的Value屬性Binding到TextBox。
通過上面的Gif圖檔可以發現,當拖動Slider時,TextBox框中的數值随着Slider的Value改變而改變,當在TextBox中輸入數值時,按Tab鍵失去焦點後,Slider的Value發生了改變。這是因為TextBox的預設Binding Mode為TwoWay,且UpdateSoureTrigger預設為LostFocus。請看下面的BindingMode示意圖,
圖示中有種Binding Mode,
OneWay,資料流向是從Source到Target;
TwoWay,資料可以從Source到Target,也可以從Target到Source,
OneWayToSource與OneWay相反,
OneTime,表示資料綁定發生後,資料源無論如何改變,Target中綁定的值都不會發生改變。
下面我們通過例子來示範這4種綁定
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<!--OneWay Binding-->
<StackPanel>
<TextBlock Text="Binding Mode: OneWay"/>
<Slider x:Name="_slider" Minimum="0" Maximum="100" Value="20"/>
<TextBox Text="{Binding ElementName=_slider,Path=Value,Mode=OneWay}"/>
</StackPanel>
<!--OneTime Binding-->
<StackPanel Grid.Row="1" Margin="0,20">
<TextBlock Text="Binding Mode: OneTime"/>
<Slider x:Name="_slider1" Minimum="0" Maximum="100" Value="20"/>
<TextBox Text="{Binding ElementName=_slider1,Path=Value,Mode=OneTime}"/>
</StackPanel>
<!--OneWayToSource Binding-->
<!--将TextBox的FontSize預設值為12-->
<StackPanel Grid.Row="2">
<TextBlock Text="Binding Mode: OneWayToSource"/>
<Slider x:Name="_slider2" Minimum="0" Maximum="100" Value="20"/>
<TextBox FontSize="{Binding ElementName=_slider2,Path=Value, Mode=OneWayToSource}"
Text="{Binding RelativeSource={RelativeSource Self},Path=FontSize}"/>
</StackPanel>
<!--TwoWay Binding-->
<StackPanel Grid.Row="3" Margin="0,20">
<TextBlock Text="Binding Mode: TwoWay"/>
<Slider x:Name="_slider3" Minimum="0" Maximum="100" Value="20"/>
<TextBox Text="{Binding ElementName=_slider3,Path=Value,Mode=TwoWay}"/>
</StackPanel>
</Grid>
在項目開發中根據實際需要選擇不同的Binding Mode,如果某些資料隻在程式啟動時顯示,後面對資料進行修改了,不需要更新,可以選擇OneTime Mode;如果對資料進行實時展示,可以選擇OneWay Mode;如果需要将資料的修改同步,那麼我們選擇TwoWay Mode。合适的綁定模式可以最優化程式的性能。
接下來看UpdateSourceTrigger,UpdateSourceTrigger有下面幾種取值,
1. LostFocus, 例如TextBox失去焦點後更新Source;
2. PropertyChanged,例如當在TextBox中輸入時,Source便同步更新;
3. Explict,需要顯示的調用
UpdateSource方法;
下面我們看Binding中另一個概念Converter;看這樣一個例子,有一個文本框顯示目前溫度,如果溫度大于35,則将文本框的前景色設定為紅色,如果溫度小于0,則顯示為藍色;
<Window.Resources>
<local:TemperatureToBrushCoverter Hot="35" Cold="0" x:Key="TemperatureToBrushCoverter"/>
</Window.Resources>
<Grid>
<TextBox Text="30" Width="200" Height="25"
Foreground="{Binding Path=Text,RelativeSource={RelativeSource Self},
Converter={StaticResource TemperatureToBrushCoverter}}"/>
</Grid>
C#:
[ValueConversion(typeof(double),typeof(Brush))]
public class TemperatureToBrushCoverter : IValueConverter
{
public double Hot { get; set; }
public double Cold { get; set; }
public TemperatureToBrushCoverter()
{
}
public TemperatureToBrushCoverter(double hot,double cold)
:this()
{
Hot = hot;
Cold = cold;
}
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
double temp;
Brush brush = Brushes.Black;
if(Double.TryParse((string)value,out temp))
{
if(temp > Hot)
{
brush = Brushes.Red;
}
else if(temp < Cold)
{
brush = Brushes.Blue;
}
}
return brush;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
注意要在XAML中引用Converter。
最後我們看一下DataBinding中的資料驗證;來看這樣一個例子,将Person對象的Age綁定到一個TextBox上,并可以對Age進行修改,年齡是一個有實際意義的值,如果Age小于0或者大于120,我們均認為其為非法值,給出相應提示。請看下面的代碼:
<Grid>
<TextBox Width="200" Height="25">
<TextBox.Text>
<Binding Path="Age" UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<local:AgeValidationRule ValidationStep="RawProposedValue"/>
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
<!--Error Template-->
<Validation.ErrorTemplate>
<ControlTemplate>
<StackPanel>
<AdornedElementPlaceholder/>
<TextBlock Text="{Binding [0].ErrorContent}" Foreground="Red"/>
</StackPanel>
</ControlTemplate>
</Validation.ErrorTemplate>
</TextBox>
</Grid>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new Person() { Age = 25};
}
}
public class Person
{
public int Age { get; set; }
}
public class AgeValidationRule : ValidationRule
{
public override ValidationResult Validate(object value, CultureInfo cultureInfo)
{
int age;
if(int.TryParse((string)value,out age))
{
if(age< 0 || age > 120)
{
return new ValidationResult(false, "This is invalide age.");
}
else
{
return new ValidationResult(true, null);
}
}
return new ValidationResult(false, "Please input valid age.");
}
}
這篇部落格的内容就到這裡了,但是WPF中Data Binding的内容遠不止這些,會在後面的部落格中展現。
感謝您的閱讀!代碼點選
這裡下載下傳。