天天看點

WPF元素綁定

原文: WPF元素綁定 資料綁定簡介:資料綁定是一種關系,該關系告訴WPF從源對象提取一些資訊,并用這些資訊設定目标對象的屬性。目标屬性是依賴項屬性。源對象可以是任何内容,從另一個WPF元素乃至ADO.NET資料對象(如DataTable)或自行建立出資料對象。綁定用的是Binding類的一個執行個體,用的名稱空間是:System.Windows.Data;

1、綁定表達式。

資料綁定表達式使用的是XAML标記擴充(是以具有花括号),用到的是System.Windows.Data.Bingding類的一個執行個體,是以綁定表達式以單詞Binding開頭,還需要兩個額外的屬性:Element屬性(源元素)和Path屬性(源元素中的屬性)。

基本文法是:{Binding ElementName=源元素 Path=源屬性}

2、将元素綁定到一起。

資料綁定最簡單的情形是,源對象是WPF元素且源屬性是依賴項屬性,依賴項屬性具有内置更改通知支援,當源對象中改變依賴屬性值時,會立即更新目标對象中的綁定屬性。

XAML代碼: 

<Window x:Class="元素綁定.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <StackPanel>
        <Slider Name="slider1" Minimum="0" Maximum="50"></Slider>
        <!--通過标記擴充和Binding關鍵字進行綁定,
            ElementName=slider1:綁定的源元素是Slider,
            Path=Value:綁定的屬性是Slider的Value屬性。
        -->
        <TextBlock FontSize="{Binding ElementName=slider1, Path=Value}">Hello,World!</TextBlock>
    </StackPanel>
</Window>      

效果圖:

WPF元素綁定

 3、綁定錯誤。 

WPF如果綁定失敗,不會引發異常來通知與資料綁定相關的問題,可以通過調試- - - - ->視窗- - - - ->輸出進行檢視。

4、綁定模式。 

BindingMode常用枚舉值
名稱 說明
OneWay 當源屬性變化時更新目标屬性(目标屬性變化時,源屬性不會變化)
TwoWay 源屬性變化時更新目标屬性,目标屬性變化時更新源屬性。
OneTime 最初根據源屬性設定目标屬性,其後所有的改變都會被忽略(直到調用BindingExpression.UpdateTarget()方法才會更新)
OneWayToSource 與OneWay類型類似,但方向相反,當目标屬性變化時更新源屬性,但目标屬性永遠不會被更新。

5、使用代碼建立綁定。

 在XAML标記中使用Binding标記擴充來聲明綁定表達式的效率是最高的。當然,也可以使用代碼建立綁定。

<Window x:Class="元素綁定.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <StackPanel>      
        <Slider Name="slider1" Minimum="0" Maximum="50" ></Slider>       
        <TextBlock Name="textBox1">Hello,World!</TextBlock>
    </StackPanel>
</Window>      

 背景代碼: 

/// <summary>
/// MainWindow.xaml 的互動邏輯
/// </summary>
public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        this.Loaded += MainWindow_Loaded;
    }

    void MainWindow_Loaded(object sender, RoutedEventArgs e)
    {
        //執行個體化Binding對象。
        Binding binding = new Binding();
        //設定綁定源對象。
        binding.Source = slider1;
        //設定綁定源屬性。
        binding.Path = new PropertyPath("Value");
        //設定綁定源的模式。
        binding.Mode = BindingMode.TwoWay;
        //為textBox1元素設定綁定(綁定需要兩個參數,一個是依賴屬性,另一個是綁定對象)。
        textBox1.SetBinding(TextBox.FontSizeProperty, binding);
    }
}      

6、移除綁定。

可使用BindingOperation類的ClearBinding()靜态方法和ClearAllBindings()靜态方法移除綁定。

//移除綁定的對象。
BindingOperations.ClearAllBindings(textBox1);
//兩個參數,移除綁定的對象和移除綁定的依賴項屬性。
BindingOperations.ClearBinding(textBox1, TextBox.FontSizeProperty);      

 7、多綁定。

就是在一個元素上為多個屬性綁定。

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition></RowDefinition>
        <RowDefinition></RowDefinition>
        <RowDefinition></RowDefinition>
    </Grid.RowDefinitions>
    
    <Slider Name="slider1" VerticalAlignment="Center" Minimum="10" Maximum="150"></Slider>
    <TextBox Name="textbox1" Margin="20" Grid.Row="1"></TextBox>
    <TextBlock Grid.Row="2" FontSize="{Binding ElementName=slider1,Path=Value}" Text="{Binding ElementName=textbox1,Path=Text}" HorizontalAlignment="Center" VerticalAlignment="Center"></TextBlock>
</Grid>      

 效果圖:

WPF元素綁定

8、綁定更新。 

一般情況下,TextBox的綁定更新是失去焦點以後才會應用到元素上,如果把UpdateSourceTrigger設定為PropertyChange,就會實時更新了。UpdateSourceTrigger常用枚舉值如下。

UpdateSourceTrigger枚舉值
PropertyChange 當目标屬性發生變化時立即更新源
LostFocus 當目标屬性發生變化且目标屬性丢失焦點時更新源
Explict 除非調用BindingExpression.UpdateSource()方法,否則無法更新源(驗證情況下,使用這個,在觸發事件的過程調用BindingExpression.UpdateSource()方法)。
Default 預設效果和大多數元素都是PropertyChange,但TextBox屬性的預設行為是LostFocus

9、綁定延遲。

在極少數情況下,需要防止資料綁定觸發操作和修改源對象,至少在某一時間段是這樣的,這個時候可以使用Binding對象的Delay屬性,機關是毫秒。如Delay=5000,就是5秒後才更新。

10、綁定到非元素。

在資料驅動的應用程式中,更常見的情況是建立從不可見對象中提取資料的綁定表達式。唯一的要求是希望顯示的資訊必須存儲在公有屬性中,WPF資料綁定基礎結構不能擷取私有資訊或公有字段。當綁定到非元素對象時,可使用Source屬性、RelativeSource屬性、DataContent屬性。

10.1)、Source。

source:該屬性是指向源對象的引用(提供資料的對象),說白了就是為源資料指派的地方。

例子1:将Source屬性指向已經準備好的靜态對象。

<TextBlock Text="{Binding Source={x:Static SystemFonts.StatusFontFamily},Path=Source}" FontSize="20"></TextBlock>      

這個綁定表達式擷取由靜态屬性屬性SystemFonts.StatusFontFamily提供的FontFamily對象,設定Binding.Source屬性時,需要借助靜态标記擴充,然後将Binding.Path屬性設定為FontFamily.Source屬性。該屬性給出了字型家族的名稱。

例子2:綁定到先前建立好的資源對象。 

<!--定義資源-->
<Window.Resources>
    <FontFamily x:Key="ResourceFamily">Hello,World</FontFamily>
</Window.Resources>

<!--引用資源-->
<TextBlock Text="{Binding Source={StaticResource ResourceFamily},Path=Source}"></TextBlock>      

10.2)、RelativeSource。

RelativeSource:這是引用,使用RelativeSource對象指向源對象,RelativeSource是一種特殊工具,當編寫控件模闆以及資料模闆時是很友善的。Relative屬性可根據相對目标對象的關系指向源對象,例如可使用RelativeSource屬性将元素綁定到自身或其父元素(不知道在元素樹中從目前元素到綁定的父元素之間有多少代)。

RelativeSourceMode枚舉值
Self 表達式綁定到統一進制素的另一進制素上。
FindAncestor

表達式綁定到父元素,WPF查找元素樹直至發現期望的父元素,為了指定父元素,還必須設定AncestorType屬性以訓示希望查找的父元素的類型,還可以使用AncestorLevel屬性略過發現的一定數量的特定元素。例如,

當在一棵樹中查找時,如果希望綁定到第三個ListBox類型的元素,應當設定:AncestorType={x:Type ListBoxItem};并且設定AncestorLevel=3,進而略過前兩個ListBoxItem元素,預設情況下AncestorLevel屬性

設定為1,找到第一個比對的元素時停止查找。

PreviousData 表達式綁定到資料綁定清單的前一個資料項,在清單項中使用這種模式。
TemplateParent 表達式綁定到應用模闆的元素。

例子: 

<StackPanel> 
    <!--方式1、綁定到父元素上-->
    <TextBlock Height="100">           
        <TextBlock.Text>
            <Binding Path="Title"> <!--建立Binding對象和設定綁定路徑為Title-->
                <Binding.RelativeSource>
                    <RelativeSource Mode="FindAncestor" AncestorType="{x:Type Window}"></RelativeSource> <!--設定綁定模式和父元素的類型-->
                </Binding.RelativeSource>
            </Binding>
        </TextBlock.Text>
    </TextBlock>

    <!--方式2、綁定到父元素上-->
    <TextBox Text="{Binding Path=Title, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}}"></TextBox>
        
    <!--綁定到自身上面,綁定屬性為自身的高-->
    <TextBox Height="50" Text="{Binding Path=Height, RelativeSource={RelativeSource Mode=Self}}"></TextBox>
</StackPanel>       

10.3)、DataContent。

DataContent:如果沒有使用Source或RelativeSource屬性指定源,WPF就從目前元素開始在元素樹中向上查找,檢查每個元素的DataContext屬性,并使用第一個非空的DataContext屬性,當要将同一個對象的多個屬性綁定到不同的元素時,DataContext屬性是非常有用的,因為可以在更高的容器對象上設定DataContext屬性。 

<!--定義一個靜态資源-->
<Window.Resources>
    <FontFamily x:Key="SourceFamily" >Hello,World</FontFamily>
</Window.Resources>

<!--通過Source普通引用-->
<StackPanel>
    <TextBlock Text="{Binding Source={StaticResource SourceFamily},Path=Source}"></TextBlock>
    <TextBlock Text="{Binding Source={StaticResource SourceFamily},Path=Source}"></TextBlock>
    <TextBlock Text="{Binding Source={StaticResource SourceFamily},Path=Source}"></TextBlock>
</StackPanel>

<!--通過DataContext形式-->
<StackPanel>
    <TextBlock Text="{Binding Source={StaticResource SourceFamily},Path=Source}"></TextBlock>
    <TextBlock Text="{Binding Source={StaticResource SourceFamily},Path=Source}"></TextBlock>
    <TextBlock Text="{Binding Source={StaticResource SourceFamily},Path=Source}"></TextBlock>
</StackPanel>

<!--通過DataContext屬性進行綁定-->
<StackPanel DataContext="{StaticResource SourceFamily}">
    <TextBlock Text="{Binding }"></TextBlock> <!--直接寫一個Binding綁定即可-->
    <TextBlock Text="{Binding }"></TextBlock>
    <TextBlock Text="{Binding Path = source}"></TextBlock>
</StackPanel>      

 End!

繼續閱讀