WPF學習(第八章) 元素綁定

1.元素綁定

元素綁定是數據綁定的一種,將源對象和目標對象的元素綁定在一起,使從源對象提取一些信息來設置目標對象的屬性。

元素綁定的好處是使得元素的交互方式自動化,當用戶修改控件時,另一元素自動更新,不需要編寫樣板代碼(這是WinForm技術不能實現的)。

2.綁定表達式

該窗口中包含兩個控件:一個Slider控件和一個單行文本TextBlock控件。通過拖動條形控件的滑塊調整文本字體大小。

顯然不用元素綁定也容易實現,可以簡單地響應Slider.ValueChanged事件,將滑塊的當前值複製到TextBlock來實現。但是使用元素綁定實現起來會更簡單。

<Slider Name="slider" Minimum="1" Maximum="40" Value="10" TickFrequency="1" TickPlacement="TopLeft" Margin="3"></Slider>
<TextBlock Name="textblock" Text="Simple Text" FontSize="{Binding ElementName=slider, Path=Value}" Margin="3"></TextBlock>

綁定表達式以單詞Binding開頭,ElementName指示源元素,Path指示源元素的屬性。之所以用Path而不用Property是因爲Path可能指向一個屬性的屬性(如FontFamily.Source)、屬性索引器(如Content.Children[0])或更多層的屬性的屬性的屬性等。

如果在上面代碼基礎上再加兩個按鈕,用於設置最小字體和最大字體。

單擊Set to Large按鈕,會運行下面代碼:

private void Button_Click_SetLarge(object sender, RoutedEventArgs e)
{
   slider.Value = slider.Maxmum;
}

實際效果是滑塊滑到最大值,文本字體大小變爲對應的最大值。

然而如果我們把代碼寫成下面的形式則不能正常工作。

private void Button_Click_SetLarge(object sender, RoutedEventArgs e)
{
   textblock.FontSize = slider.Maxmum;
}


上面代碼中修改了文本的大小,但是滑塊沒有更新。而且再調整滑塊時文本大小不會跟着變化。上面代碼破壞了元素綁定。

3.綁定模式

可以通過綁定模式來解決上述問題。代碼如下:

<TextBlock Name="textblock" Text="Simple Text" FontSize="{Binding ElementName=slider, Path=Value, Mode=TwoWay}" Margin="3"></TextBlock>

Binding的Mode屬性爲枚舉類型BindingMode。具體的值有:

OneWay:單向綁定。

TwoWay:雙向綁定。

OneTime:一次綁定。只在程序運行時更新目標值。

OneWayToSource:反向單向綁定。

Default:缺省值。默認是單向綁定。

4.使用代碼創建綁定

也可以使用C#代碼來創建綁定:

Binding binding = new Binding();
binding.Source = slider;
binding.Path = new PropertyPath("Value");
binding.Mode = BindingMode.TwoWay;
textblock.SetBinding(TextBlock.FontSizeProperty, binding);


使用下面代碼移除綁定

BindingOperations.ClearBinding(textblock, TextBlock.FontSizeProperty);

BindingOperations.ClearAllBindings(textblock);

5.更新時機問題

從目標到源的更新可能不會立即發生。主要出現在TwoWay和OneWayToSource模式下。例如,用一個文本輸入框TextBox和Slider的Value綁定,通過在TextBox裏輸入數字來動態修改Slider的Value。如果使用TwoWay模式,則輸入數字後Slider.Value不會自動更新,只有當TextBox失去焦點時才更新。

  

<TextBox Name="textbox" Height="23" TextWrapping="Wrap" Text="{Binding ElementName=slider, Path=Value, Mode=TwoWay}" Width="120"/>


如果不想出現這種情況,想要在TextBox輸入任意值時就更新Slider,則有兩種方法可以解決:

1.在上面代碼里加入UpdateSourceTrigger=PropertyChanged使得只要輸入內容改變就更新而不是失去焦點才更新;

2.讓Slider去綁定TextBox,Mode還是TwoWay。

6.綁定到非元素對象

之前我們用到的是Binding.ElementName元素對象,它必須是XAML文件裏的元素。然而我們也可以綁定其他非元素對象,例如綁定系統的靜態數據對象、綁定資源等。

當綁定非元素對象時,需用到下面三種之一來替代ElementName

(1)Source:通常是一個已存在的靜態對象。例如綁定Net類庫的靜態變量代碼如下:

<TextBlock Name="textblock" Text="{Binding Source={x:Static SystemFonts.IconFontFamily}, Path=Source}" Margin="3"></TextBlock>


綁定程序靜態資源的代碼如下:

 

<Window.Resources>
        <FontFamily x:Key="CustomFont">Calibri1</FontFamily>
</Window.Resources>
<TextBlock Name="textblock2" Text="{Binding Source={StaticResource CustomFont}, Path=Source}" Margin="3"></TextBlock>


(2)RelativeSource:從上下文找到符合綁定要求的元素進行綁定。包括在當前元素的所有屬性進行搜索,和在其父節點、祖父節點一直往上的上下文搜索。

例如:綁定當前控件自己的Margin的值,如下:

<TextBlock Name="textblock3" Margin="4,4,4,4" Text="{Binding RelativeSource={RelativeSource Self},Path=Margin}"></TextBlock>


例如:綁定當前控件祖先節點Window窗口的名字,如下:

<TextBlock Name="textblock3" Text="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}},Path=Title}"></TextBlock>


(3)DataContext:如果有大量元素綁定同一對象,代碼標記會有很長的重複。使用DataContext綁定源可以簡化代碼。例如下面的代碼就很臃腫:

<StackPanel>
<TextBlock Text="{Binding Source={x:Static SystemFonts.IconFontFamily},Path=Source}">
</TextBlock>
<TextBlock Text="{Binding Source={x:Static SystemFonts.IconFontFamily},Path=LineSpacing}"> </TextBlock>
<TextBlock Text="{Binding Source={x:Static SystemFonts.IconFontFamily}, Path=FamilyTypefaces[0].Style}"> </TextBlock>
</StackPanel>


 代碼中所有TextBlock綁定相同的數據SystemFonts.IconFontFamily,但是它們綁定的屬性不同。我們使用DataContext對代碼進行簡化如下:

<StackPanel DataContext="{x:Static SystemFonts.IconFontFamily}">
<TextBlock Text="{Binding Path=Source}">
</TextBlock>
<TextBlock Text="{Binding Path=LineSpacing}"> </TextBlock>
<TextBlock Text="{Binding Path=FamilyTypefaces[0].Style}"> </TextBlock>
</StackPanel>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章