三、綁定模式
通過上一文章中的示例,學習了簡單的綁定方式。在這里的示例,要學習一下綁定的模式,和模式的使用效果。
首先,我們來做一個簡單示例,這個示例是根據ListBox中的選中項,去改變TextBlock的背景色。將 TextBlock 的背景色綁定到在 ListBox 中選擇的顏色。在下面的代碼中針對TextBlock的 Background 屬性使用綁定語法綁定從 ListBox 中選擇的值。代碼如下。
<StackPanel Grid.Row="1"> <TextBlock Width="248" Height="24" Text="顏色:" TextWrapping="Wrap"/> <ListBox x:Name="listColor" Width="248" Height="56"> <ListBoxItem Content="Blue"/> <ListBoxItem Content="Red"/> <ListBoxItem Content="Green"/> <ListBoxItem Content="Gray"/> <ListBoxItem Content="Cyan"/> <ListBoxItem Content="GreenYellow"/> <ListBoxItem Content="Orange"/> </ListBox> <TextBlock Width="248" Height="24" Text="改變背景色:" /> <TextBlock Width="248" Height="24" Background="{Binding ElementName=listColor, Path=SelectedItem.Content, Mode=OneWay}"> </TextBlock> </StackPanel>
如果用戶在 ListBox 中選擇了一種顏色,那么TextBlock 的背景色會變為選定的顏色(如下圖1)。
圖1
接下來我們對上面的示例進行一些修改:
1) 同一個數據源綁定到兩個或多個控件上。如我們的示例中把ListBox的選中項綁定到TextBox與TextBlock。
2) 在綁定語法中增加一個 Mode 屬性,即綁定模式。對於我們的示例,我們把TextBlock的綁定語法中的Mode屬性設為 OneWay 。把TextBox的綁定語法中的Mode屬性設為TwoWay。
對於示例中的Mode進行一下簡單說明(具體可以參見前一篇):
1)使用 OneWay 綁定時,每當數據源(ListBox)發生變化時,數據就會從數據源流向目標(TextBlock)。
2)OneTime 綁定也會將數據從源發送到目標;但是,僅當啟動了應用程序或 DataContext 發生更改時才會如此操作,因此,它不會偵聽源中的更改通知。
3)OneWayToSource 綁定會將數據從目標發送到源。
4)TwoWay 綁定會將源數據發送到目標,但如果目標屬性的值發生變化,則會將它們發回給源。
下面就是修改后的示例代碼,功能是將 TextBlock (OneWay) 和 TextBox (TwoWay) 綁定到 ListBox 的代碼:
<StackPanel Grid.Row="1"> <TextBlock Width="248" Height="24" Text="顏色:" TextWrapping="Wrap"/> <ListBox x:Name="listColor" Width="248" Height="56"> <ListBoxItem Content="Blue"/> <ListBoxItem Content="Red"/> <ListBoxItem Content="Green"/> <ListBoxItem Content="Gray"/> <ListBoxItem Content="Cyan"/> <ListBoxItem Content="GreenYellow"/> <ListBoxItem Content="Orange"/> </ListBox> <TextBlock Width="248" Height="24" Text="改變背景色:" /> <TextBlock Width="248" Height="24" Text="{Binding ElementName=listColor, Path=SelectedItem.Content, Mode=OneWay}" Background="{Binding ElementName=listColor, Path=SelectedItem.Content, Mode=OneWay}"> </TextBlock> <TextBox Name="txtTwoWay" Text="{Binding ElementName=listColor,Path=SelectedItem.Content,Mode=TwoWay}" Background="{Binding ElementName=listColor,Path=SelectedItem.Content,Mode=TwoWay}"></TextBox> </StackPanel>
圖 2
在上述示例中,對TextBlock使用了 OneWay 綁定模式,因為我希望只有當選擇了 ListBox 中的某一項之后,應用程序將選定的 ListBoxItem(數據源)發送到 TextBlock。我不希望 TextBlock 的變更會影響到 ListBox中的內容。
我對TextBox使用 TwoWay 綁定模式,因為我希望用戶在 ListBox 中選擇一種顏色后,該顏色就會顯示在 TextBox 中,並且其背景色也會隨之相應變化。如果該用戶在 TextBox 中鍵入了一種顏色(例如Pink),ListBox 中剛才選中的顏色名稱就會被更新(即從目標到數據源),當鼠標再次點擊這條修改后的數據時,新值就會被再次發送到TextBox上。這意味着 TextBlock 也會隨之改變。(請參見圖 2)。
如果我將 TwoWay 模式改回到 OneWay,用戶則可以編輯 TextBox 中的顏色,但是不會將TextBox中輸入的值去替換ListBox中選中項的值。
綁定模式如何應用呢?下面是個人的一點見解:
1)當只想讓用戶看到數據,而不希望用戶去修改數據時,可以采用 OneWay 模式,類似winform中的只讀屬性。
2)當希望用戶可以對控件中的數據進行修改,同時讓用戶修改的數據更新到數據源(DataSet、對象、XML 或其他綁定控件)中時,可以使用 TwoWay 綁定。
3)如果想讓用戶修改數據源中的數據,而又不想使用TowWay模式,就可以使用 OneWayToSource 綁定。OneWayToSource模式允許通過在原來被看作是綁定源的對象中放置綁定表達式,從而翻轉源和目標。
4)當你的界面中的一系列只讀控件均被綁定了數據,並且當用戶刷新了數據源時,希望綁定控件中的值仍保持不變,可以使用 OneTime 綁定。此外,當源沒有實現 INotifyPropertyChanged 時,OneTime 綁定模式也是一個不錯的選擇。
說明:綁定目標中的修改何時去修改數據源
在上面的例子中,TextBox 使用了 TwoWay 綁定模式,所以當TextBox 失去焦點時WPF會使用TextBox中的值改變ListBox中的值。如果你不想在TextBox失去焦點時,就去修改ListBox中的值,可以為 UpdateSourceTrigger 指定值,它是用於定義何時更新源的綁定屬性。可以為 UpdateSourceTrigger 設置三個值:Explicit、LostFocus 和 PropertyChanged。
如果將 UpdateSourceTrigger 設置為 Explicit,則不會更新源,除非從代碼中調用 BindingExpression.UpdateSource 方法。設置為LostFocus ,(TextBox 控件的默認值)指示數據源綁定的控件失去焦點時才會更新。PropertyChanged 值綁定控件的綁定屬性每次發生更改時就去更新數據源中的值。