C#?WPF編程之元素綁定詳解
數(shù)據(jù)綁定是一種關(guān)系,該關(guān)系告訴WPF從源對象提取一下信息,并用這些信息設(shè)置目標(biāo)對象的屬性。目標(biāo)屬性始終是依賴項屬性,通常位于WPF元素中,WPF數(shù)據(jù)綁定的最終目標(biāo)是在用戶界面中顯示一下信息。
將元素綁定到一起
數(shù)據(jù)綁定的最簡單情形是,源對象是WPF元素而且源屬性是依賴項屬性。依賴項屬性具有內(nèi)置的更改通知支持。當(dāng)源對象中改變屬性值時會立即更新目標(biāo)對象中的綁定屬性。
常用的綁定屬性字段:
- ElementName:綁定元素名稱
- Path:綁定值
- Mode:綁定模式
- UpdateSourceTrigger:綁定更新方式
- Delay:延時時間
<TextBlock x:Name="textFontSize" Text="{Binding ElementName=textInput, Path=Text, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged,Delay=500}"></TextBlock>
簡單示例,通過Slider控制TextBlock文本字體大?。?/p>
<StackPanel> <Slider x:Name="sliderFontSize" Margin="3" Minimum="1" Maximum="40" Value="10" TickFrequency="1" TickPlacement="TopLeft"></Slider> <TextBlock x:Name="textBlock" Margin="10" Text="簡單文本內(nèi)容" FontSize="{Binding ElementName=sliderFontSize, Path=Value}"></TextBlock> </StackPanel>
綁定表達(dá)式
數(shù)據(jù)綁定表達(dá)式使用XAML標(biāo)記擴(kuò)展。因為正在創(chuàng)建System.Windows.Data.Binding類的一個實例,所以綁定表達(dá)式以單詞Binding開頭。至少需要設(shè)置兩個屬性:ElementName屬性(指示源元素)和Path屬性(指示源元素中的屬性)。
如果希望引用附加屬性(在另一個類中定義但應(yīng)用于綁定元素的屬性),需要再圓括號中封裝屬性名稱。如,綁定到Grid控件中的某個元素,路徑(Grid.Row)將檢索放置元素的行號。
綁定錯誤
WPF不會引發(fā)異常來通知與數(shù)據(jù)綁定相關(guān)的問題。如果指定元素或?qū)傩圆淮嬖?,那么不會收到任何指示?/p>
綁定模式
數(shù)據(jù)綁定的一個特性是目標(biāo)會被自動更新,而不考慮源的修改方式。
BindingMode枚舉值
名稱 | 說明 |
---|---|
OneWay | 當(dāng)源屬性變化時更新目標(biāo)屬性 |
TwoWay | 當(dāng)源屬性變化時更新目標(biāo)屬性,并且當(dāng)目標(biāo)屬性變化時更新源屬性 |
OneTime | 最初根據(jù)源屬性值設(shè)置目標(biāo)屬性 |
OneWayToSource | 與OnWay類型類似,但方向相反。當(dāng)目標(biāo)屬性變化時更新源屬性 |
Default | 此類綁定依賴于目標(biāo)屬性。既可以是雙向的,也可以是單向的。除非明確指定了另一種模式,否則所有綁定都使用該方法 |
示例,雙向綁定模式:
<StackPanel> <Slider x:Name="sliderFontSize" Margin="3" Width="500" Minimum="1" Maximum="40" Value="10" TickFrequency="1" TickPlacement="TopLeft"></Slider> <TextBlock x:Name="textBlock" Margin="10" Text="簡單文本內(nèi)容" FontSize="{Binding ElementName=sliderFontSize, Path=Value, Mode=TwoWay}"></TextBlock> <Button x:Name="smallBtn" Margin="10" Width="100" Click="smallBtn_Click">小字體</Button> <Button x:Name="largeBtn" Margin="10" Width="100" Click="largeBtn_Click">大字體</Button> </StackPanel>
private void smallBtn_Click(object sender, RoutedEventArgs e) { textBlock.FontSize = 15; } private void largeBtn_Click(object sender, RoutedEventArgs e) { textBlock.FontSize = 30; }
代碼創(chuàng)建綁定
在構(gòu)建窗口時,在XAML標(biāo)記中使用Binding標(biāo)記擴(kuò)展來聲明綁定表達(dá)式通常最高效。但也可以使用代碼來創(chuàng)建綁定:
示例,代碼創(chuàng)建綁定:
Binding binding = new Binding(); binding.Source = sliderFontSize; binding.Path = new PropertyPath("Value"); binding.Mode = BindingMode.TwoWay; blockText.SetBinding(TextBlock.FontSize, binding);
移除綁定
可以通過代碼使用BindingOperation類的兩個靜態(tài)方法移除綁定。
- ClearBinding()方法:使用依賴項屬性的引用作為參數(shù),刪除指定的數(shù)據(jù)綁定;
- ClearAllBinding()方法:為元素刪除所有數(shù)據(jù)綁定;
BindingOperation.ClearAllBinding(blockText);
需要使用代碼綁定的一些特殊情況:
- 創(chuàng)建動態(tài)綁定
- 刪除綁定
使用代碼檢索綁定
可使用代碼檢索綁定并檢查其屬性,而不必考慮綁定最初是用代碼還是標(biāo)記創(chuàng)建的。
獲取綁定信息的兩種方式:
使用靜態(tài)方法BindingOperations.GetBinding()來檢索相應(yīng)的Binding對象。需要提供兩個參數(shù):綁定元素以及具有綁定表達(dá)式的屬性。
<TextBlock x:Name="textBlock" Margin="10" Text="簡單文本內(nèi)容" FontSize="{Binding ElementName=sliderFontSize, Path=Value"></TextBlock>
Binding binding = BindingOperations.GetBinding(textBlock, TextBlock.FontSize);
一旦獲取到綁定對象,就可以檢查其屬性。如:
- Binding.ElementName:綁定元素名;
- Binding.Path:綁定值;
- BindingMode:綁定模式;
通過調(diào)用BindingOperations.GetBindingExpression()方法獲得更實用的BindingExpression對象:
BindingExpression expression = BindingOperations.GetBingdingExpression(textBlock, TextBlock.FontSize); // 獲取源元素 Slider boundObj = (Slider)expression.ResolvedSource; string boundData = boundObj.FontSize;
多綁定
可以綁定元素的多個屬性。
示例:綁定了 TextBlock元素的 FontSize,Text 和 Foreground三個屬性
<StackPanel Width="500"> <Slider x:Name="sliderFontSize" Minimum="10" Maximum="40" Value="20"></Slider> <TextBox x:Name="textInput">請輸入內(nèi)容</TextBox> <ListBox x:Name="listboxColor" SelectedIndex="0"> <ListBoxItem Foreground="Red">Red</ListBoxItem> <ListBoxItem Foreground="Green">Green</ListBoxItem> <ListBoxItem Foreground="Blue">Blue</ListBoxItem> </ListBox> <TextBlock x:Name="textShow" Margin="5" FontSize="{Binding ElementName=sliderFontSize, Path=Value}" Text="{Binding ElementName=textInput, Path=Text}" Foreground="{Binding ElementName=listboxColor, Path=SelectedItem.Foreground}"></TextBlock> </StackPanel>
綁定更新
綁定數(shù)據(jù)的更新行為由Binding.UpdateSourceTrigger屬性控制,枚舉值有:
稱 | 說明 |
---|---|
PropertyChanged | 當(dāng)目標(biāo)屬性發(fā)生變化時立即更新源 |
LostFocus | 當(dāng)目標(biāo)屬性發(fā)生變化并且目標(biāo)丟失焦點時更新源 |
Explicit | 除非調(diào)用BindingExpression.UpdateSource()方法,否則無法更新源 |
Default | 更加目標(biāo)屬性的元素數(shù)據(jù)確定更新行為 |
例如,添加了UpdateSourceTrigger=PropertyChanged
<TextBlock x:Name="textFontSize" Text="{Binding ElementName=textInput, Path=Text, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"></TextBlock>
綁定延時
下極少數(shù)情況下,需要防止數(shù)據(jù)綁定觸發(fā)操作和修改源對象,至少需要延遲一段時間。這種情況可以使用Binding對象的Delay屬性。等待數(shù)毫秒,之后再提交更改。
例如:添加了Delay=500
<TextBlock x:Name="textFontSize" Text="{Binding ElementName=textInput, Path=Text, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged,Delay=500}"></TextBlock>
綁定到非元素對象
在數(shù)據(jù)驅(qū)動的應(yīng)用程序中,更常見的情況是創(chuàng)建從不可見對象中提取數(shù)據(jù)的綁定表達(dá)式。唯一要求是希望顯示的信息必須存儲在公有屬性中。WPF數(shù)據(jù)綁定基礎(chǔ)結(jié)構(gòu)不能獲取私有信息或公有字段。
當(dāng)綁定到非元素對象時,需要放棄Binding.ElementName屬性,并使用以下屬性中的一個:
- Source:該屬性是指向源對象的引用,也就是提供數(shù)據(jù)的對象。
- RelativeSource:這是引用,使用RelateveSource對象指向源對象。有了這個附加層,可在當(dāng)前元素的基礎(chǔ)上構(gòu)建引用。
- DataContext:如果沒有使用Source或RelativeSource屬性指定源,WPF就從當(dāng)前元素開始在元素樹中向上查找。檢查每個元素的DataContext屬性,并使用第一個非空的DataContext屬性。
Source屬性
Source屬性非常簡單。唯一的問題是為了進(jìn)行綁定,需要具有數(shù)據(jù)對象。有多種方法獲取數(shù)據(jù)對象??蓮馁Y源中提取數(shù)據(jù)對象,可通過編寫代碼生成數(shù)據(jù)對象,也可在數(shù)據(jù)提供程序的幫助下獲取數(shù)據(jù)對象。
最簡單的選擇是將Source屬性指向一些已經(jīng)準(zhǔn)備好了的靜態(tài)對象。如,使用來自.NET類庫的組件:
<TextBlock Text="{Binding Source={x:Static SystemFonts.IconFontFamily},Path=Source}"></TextBlock>
這個綁定表達(dá)式獲取由靜態(tài)屬性SystemFonts.IconFontFamily提供的FontFamily對象。注意需要借助靜態(tài)標(biāo)記擴(kuò)展Static。
綁定到先前作為資源創(chuàng)建的對象。如,標(biāo)記創(chuàng)建指向Calibri字體的FontFamily對象:
<Window.Resources> <FontFamily x:Key="CustomFont">Calibri</FontFamily> </Window.Resources>
TextBlock元素會被綁定到該資源:
<TextBlock Text="{Binding Source={StaticResource CustomFont}, Path=Source}"></TextBlock>
RelativeSource屬性
通過RelativeSource屬性可根據(jù)相對目標(biāo)對象的關(guān)系指向源對象。例如,可使用RelativeSource屬性將元素綁定到自身或其父元素。RelativeSource對象使用FindAncestor模式,該模式告知查找到元素樹直到發(fā)現(xiàn)AncestorType屬性定義的元素類型。
<TextBlock> <TextBlock.Text> <Binding Path="Title"> <Binding.RelativeSource> <RelativeSource Mode="FindAncestor" AncestorType="{x:Type Window}"/> </Binding.RelativeSource> </Binding> </TextBlock.Text> </TextBlock>
編寫綁定更常用的方法是使用Binding和RelativeSource標(biāo)記擴(kuò)展,將其合并到一個字符串種,如下所示:
<TextBlock Text="{Binding Path=Title, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}"> </TextBlock>
RelativeSourceMode 枚舉值
名稱 | 說明 |
---|---|
self | 表達(dá)是綁定到同一元素的另一個屬性上 |
FindAncestor | 表達(dá)式綁定到父元素 |
PreviousData | 表達(dá)式綁定到數(shù)據(jù)綁定列表的前一個數(shù)據(jù)項。在列表元素中會使用到這種模式 |
TemplateParent | 表達(dá)式綁定到應(yīng)用模板的元素。只有當(dāng)綁定位于控件模板或數(shù)據(jù)模板內(nèi)部時,這種模式才能工作 |
DataContent屬性
在某些情況下,會將大量元素綁定到同一個對象。
可使用和設(shè)置Binding.Source屬性相同的方法設(shè)置元素的DataContext屬性。
<StackPanel DataContext="{x:Static SystemFonts.IconFontFamily}"> <TextBlock Text="{Binding Path=Source}"></TextBlock> </StackPanel>
以上就是C# WPF編程之元素綁定詳解的詳細(xì)內(nèi)容,更多關(guān)于WPF元素綁定的資料請關(guān)注腳本之家其它相關(guān)文章!