C#?WPF編程之元素綁定詳解
數(shù)據(jù)綁定是一種關系,該關系告訴WPF從源對象提取一下信息,并用這些信息設置目標對象的屬性。目標屬性始終是依賴項屬性,通常位于WPF元素中,WPF數(shù)據(jù)綁定的最終目標是在用戶界面中顯示一下信息。
將元素綁定到一起
數(shù)據(jù)綁定的最簡單情形是,源對象是WPF元素而且源屬性是依賴項屬性。依賴項屬性具有內置的更改通知支持。當源對象中改變屬性值時會立即更新目標對象中的綁定屬性。
常用的綁定屬性字段:
- 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="簡單文本內容"
FontSize="{Binding ElementName=sliderFontSize, Path=Value}"></TextBlock>
</StackPanel>

綁定表達式
數(shù)據(jù)綁定表達式使用XAML標記擴展。因為正在創(chuàng)建System.Windows.Data.Binding類的一個實例,所以綁定表達式以單詞Binding開頭。至少需要設置兩個屬性:ElementName屬性(指示源元素)和Path屬性(指示源元素中的屬性)。
如果希望引用附加屬性(在另一個類中定義但應用于綁定元素的屬性),需要再圓括號中封裝屬性名稱。如,綁定到Grid控件中的某個元素,路徑(Grid.Row)將檢索放置元素的行號。
綁定錯誤
WPF不會引發(fā)異常來通知與數(shù)據(jù)綁定相關的問題。如果指定元素或屬性不存在,那么不會收到任何指示;
綁定模式
數(shù)據(jù)綁定的一個特性是目標會被自動更新,而不考慮源的修改方式。
BindingMode枚舉值
| 名稱 | 說明 |
|---|---|
| OneWay | 當源屬性變化時更新目標屬性 |
| TwoWay | 當源屬性變化時更新目標屬性,并且當目標屬性變化時更新源屬性 |
| OneTime | 最初根據(jù)源屬性值設置目標屬性 |
| OneWayToSource | 與OnWay類型類似,但方向相反。當目標屬性變化時更新源屬性 |
| Default | 此類綁定依賴于目標屬性。既可以是雙向的,也可以是單向的。除非明確指定了另一種模式,否則所有綁定都使用該方法 |

示例,雙向綁定模式:
<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="簡單文本內容"
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)建綁定
在構建窗口時,在XAML標記中使用Binding標記擴展來聲明綁定表達式通常最高效。但也可以使用代碼來創(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)綁定
- 刪除綁定
使用代碼檢索綁定
可使用代碼檢索綁定并檢查其屬性,而不必考慮綁定最初是用代碼還是標記創(chuàng)建的。
獲取綁定信息的兩種方式:
使用靜態(tài)方法BindingOperations.GetBinding()來檢索相應的Binding對象。需要提供兩個參數(shù):綁定元素以及具有綁定表達式的屬性。
<TextBlock x:Name="textBlock" Margin="10" Text="簡單文本內容"
FontSize="{Binding ElementName=sliderFontSize, Path=Value"></TextBlock>
Binding binding = BindingOperations.GetBinding(textBlock, TextBlock.FontSize);
一旦獲取到綁定對象,就可以檢查其屬性。如:
- Binding.ElementName:綁定元素名;
- Binding.Path:綁定值;
- BindingMode:綁定模式;
通過調用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">請輸入內容</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 | 當目標屬性發(fā)生變化時立即更新源 |
| LostFocus | 當目標屬性發(fā)生變化并且目標丟失焦點時更新源 |
| Explicit | 除非調用BindingExpression.UpdateSource()方法,否則無法更新源 |
| Default | 更加目標屬性的元素數(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ù)驅動的應用程序中,更常見的情況是創(chuàng)建從不可見對象中提取數(shù)據(jù)的綁定表達式。唯一要求是希望顯示的信息必須存儲在公有屬性中。WPF數(shù)據(jù)綁定基礎結構不能獲取私有信息或公有字段。
當綁定到非元素對象時,需要放棄Binding.ElementName屬性,并使用以下屬性中的一個:
- Source:該屬性是指向源對象的引用,也就是提供數(shù)據(jù)的對象。
- RelativeSource:這是引用,使用RelateveSource對象指向源對象。有了這個附加層,可在當前元素的基礎上構建引用。
- DataContext:如果沒有使用Source或RelativeSource屬性指定源,WPF就從當前元素開始在元素樹中向上查找。檢查每個元素的DataContext屬性,并使用第一個非空的DataContext屬性。
Source屬性
Source屬性非常簡單。唯一的問題是為了進行綁定,需要具有數(shù)據(jù)對象。有多種方法獲取數(shù)據(jù)對象??蓮馁Y源中提取數(shù)據(jù)對象,可通過編寫代碼生成數(shù)據(jù)對象,也可在數(shù)據(jù)提供程序的幫助下獲取數(shù)據(jù)對象。
最簡單的選擇是將Source屬性指向一些已經準備好了的靜態(tài)對象。如,使用來自.NET類庫的組件:
<TextBlock Text="{Binding Source={x:Static SystemFonts.IconFontFamily},Path=Source}"></TextBlock>
這個綁定表達式獲取由靜態(tài)屬性SystemFonts.IconFontFamily提供的FontFamily對象。注意需要借助靜態(tài)標記擴展Static。
綁定到先前作為資源創(chuàng)建的對象。如,標記創(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ù)相對目標對象的關系指向源對象。例如,可使用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標記擴展,將其合并到一個字符串種,如下所示:
<TextBlock Text="{Binding Path=Title,
RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}">
</TextBlock>
RelativeSourceMode 枚舉值
| 名稱 | 說明 |
|---|---|
| self | 表達是綁定到同一元素的另一個屬性上 |
| FindAncestor | 表達式綁定到父元素 |
| PreviousData | 表達式綁定到數(shù)據(jù)綁定列表的前一個數(shù)據(jù)項。在列表元素中會使用到這種模式 |
| TemplateParent | 表達式綁定到應用模板的元素。只有當綁定位于控件模板或數(shù)據(jù)模板內部時,這種模式才能工作 |
DataContent屬性
在某些情況下,會將大量元素綁定到同一個對象。
可使用和設置Binding.Source屬性相同的方法設置元素的DataContext屬性。
<StackPanel DataContext="{x:Static SystemFonts.IconFontFamily}">
<TextBlock Text="{Binding Path=Source}"></TextBlock>
</StackPanel>以上就是C# WPF編程之元素綁定詳解的詳細內容,更多關于WPF元素綁定的資料請關注腳本之家其它相關文章!

