C#?WPF編程之元素綁定詳解
數(shù)據(jù)綁定是一種關(guān)系,該關(guān)系告訴WPF從源對(duì)象提取一下信息,并用這些信息設(shè)置目標(biāo)對(duì)象的屬性。目標(biāo)屬性始終是依賴(lài)項(xiàng)屬性,通常位于WPF元素中,WPF數(shù)據(jù)綁定的最終目標(biāo)是在用戶(hù)界面中顯示一下信息。
將元素綁定到一起
數(shù)據(jù)綁定的最簡(jiǎn)單情形是,源對(duì)象是WPF元素而且源屬性是依賴(lài)項(xiàng)屬性。依賴(lài)項(xiàng)屬性具有內(nèi)置的更改通知支持。當(dāng)源對(duì)象中改變屬性值時(shí)會(huì)立即更新目標(biāo)對(duì)象中的綁定屬性。
常用的綁定屬性字段:
- ElementName:綁定元素名稱(chēng)
- Path:綁定值
- Mode:綁定模式
- UpdateSourceTrigger:綁定更新方式
- Delay:延時(shí)時(shí)間
<TextBlock x:Name="textFontSize" Text="{Binding ElementName=textInput, Path=Text, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged,Delay=500}"></TextBlock>
簡(jiǎn)單示例,通過(guò)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="簡(jiǎn)單文本內(nèi)容" FontSize="{Binding ElementName=sliderFontSize, Path=Value}"></TextBlock> </StackPanel>
綁定表達(dá)式
數(shù)據(jù)綁定表達(dá)式使用XAML標(biāo)記擴(kuò)展。因?yàn)檎趧?chuàng)建System.Windows.Data.Binding類(lèi)的一個(gè)實(shí)例,所以綁定表達(dá)式以單詞Binding開(kāi)頭。至少需要設(shè)置兩個(gè)屬性:ElementName屬性(指示源元素)和Path屬性(指示源元素中的屬性)。
如果希望引用附加屬性(在另一個(gè)類(lèi)中定義但應(yīng)用于綁定元素的屬性),需要再圓括號(hào)中封裝屬性名稱(chēng)。如,綁定到Grid控件中的某個(gè)元素,路徑(Grid.Row)將檢索放置元素的行號(hào)。
綁定錯(cuò)誤
WPF不會(huì)引發(fā)異常來(lái)通知與數(shù)據(jù)綁定相關(guān)的問(wèn)題。如果指定元素或?qū)傩圆淮嬖冢敲床粫?huì)收到任何指示;
綁定模式
數(shù)據(jù)綁定的一個(gè)特性是目標(biāo)會(huì)被自動(dòng)更新,而不考慮源的修改方式。
BindingMode枚舉值
名稱(chēng) | 說(shuō)明 |
---|---|
OneWay | 當(dāng)源屬性變化時(shí)更新目標(biāo)屬性 |
TwoWay | 當(dāng)源屬性變化時(shí)更新目標(biāo)屬性,并且當(dāng)目標(biāo)屬性變化時(shí)更新源屬性 |
OneTime | 最初根據(jù)源屬性值設(shè)置目標(biāo)屬性 |
OneWayToSource | 與OnWay類(lèi)型類(lèi)似,但方向相反。當(dāng)目標(biāo)屬性變化時(shí)更新源屬性 |
Default | 此類(lèi)綁定依賴(lài)于目標(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="簡(jiǎn)單文本內(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)建窗口時(shí),在XAML標(biāo)記中使用Binding標(biāo)記擴(kuò)展來(lái)聲明綁定表達(dá)式通常最高效。但也可以使用代碼來(lái)創(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);
移除綁定
可以通過(guò)代碼使用BindingOperation類(lèi)的兩個(gè)靜態(tài)方法移除綁定。
- ClearBinding()方法:使用依賴(lài)項(xiàng)屬性的引用作為參數(shù),刪除指定的數(shù)據(jù)綁定;
- ClearAllBinding()方法:為元素刪除所有數(shù)據(jù)綁定;
BindingOperation.ClearAllBinding(blockText);
需要使用代碼綁定的一些特殊情況:
- 創(chuàng)建動(dòng)態(tài)綁定
- 刪除綁定
使用代碼檢索綁定
可使用代碼檢索綁定并檢查其屬性,而不必考慮綁定最初是用代碼還是標(biāo)記創(chuàng)建的。
獲取綁定信息的兩種方式:
使用靜態(tài)方法BindingOperations.GetBinding()來(lái)檢索相應(yīng)的Binding對(duì)象。需要提供兩個(gè)參數(shù):綁定元素以及具有綁定表達(dá)式的屬性。
<TextBlock x:Name="textBlock" Margin="10" Text="簡(jiǎn)單文本內(nèi)容" FontSize="{Binding ElementName=sliderFontSize, Path=Value"></TextBlock>
Binding binding = BindingOperations.GetBinding(textBlock, TextBlock.FontSize);
一旦獲取到綁定對(duì)象,就可以檢查其屬性。如:
- Binding.ElementName:綁定元素名;
- Binding.Path:綁定值;
- BindingMode:綁定模式;
通過(guò)調(diào)用BindingOperations.GetBindingExpression()方法獲得更實(shí)用的BindingExpression對(duì)象:
BindingExpression expression = BindingOperations.GetBingdingExpression(textBlock, TextBlock.FontSize); // 獲取源元素 Slider boundObj = (Slider)expression.ResolvedSource; string boundData = boundObj.FontSize;
多綁定
可以綁定元素的多個(gè)屬性。
示例:綁定了 TextBlock元素的 FontSize,Text 和 Foreground三個(gè)屬性
<StackPanel Width="500"> <Slider x:Name="sliderFontSize" Minimum="10" Maximum="40" Value="20"></Slider> <TextBox x:Name="textInput">請(qǐng)輸入內(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屬性控制,枚舉值有:
稱(chēng) | 說(shuō)明 |
---|---|
PropertyChanged | 當(dāng)目標(biāo)屬性發(fā)生變化時(shí)立即更新源 |
LostFocus | 當(dāng)目標(biāo)屬性發(fā)生變化并且目標(biāo)丟失焦點(diǎn)時(shí)更新源 |
Explicit | 除非調(diào)用BindingExpression.UpdateSource()方法,否則無(wú)法更新源 |
Default | 更加目標(biāo)屬性的元素?cái)?shù)據(jù)確定更新行為 |
例如,添加了UpdateSourceTrigger=PropertyChanged
<TextBlock x:Name="textFontSize" Text="{Binding ElementName=textInput, Path=Text, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"></TextBlock>
綁定延時(shí)
下極少數(shù)情況下,需要防止數(shù)據(jù)綁定觸發(fā)操作和修改源對(duì)象,至少需要延遲一段時(shí)間。這種情況可以使用Binding對(duì)象的Delay屬性。等待數(shù)毫秒,之后再提交更改。
例如:添加了Delay=500
<TextBlock x:Name="textFontSize" Text="{Binding ElementName=textInput, Path=Text, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged,Delay=500}"></TextBlock>
綁定到非元素對(duì)象
在數(shù)據(jù)驅(qū)動(dòng)的應(yīng)用程序中,更常見(jiàn)的情況是創(chuàng)建從不可見(jiàn)對(duì)象中提取數(shù)據(jù)的綁定表達(dá)式。唯一要求是希望顯示的信息必須存儲(chǔ)在公有屬性中。WPF數(shù)據(jù)綁定基礎(chǔ)結(jié)構(gòu)不能獲取私有信息或公有字段。
當(dāng)綁定到非元素對(duì)象時(shí),需要放棄Binding.ElementName屬性,并使用以下屬性中的一個(gè):
- Source:該屬性是指向源對(duì)象的引用,也就是提供數(shù)據(jù)的對(duì)象。
- RelativeSource:這是引用,使用RelateveSource對(duì)象指向源對(duì)象。有了這個(gè)附加層,可在當(dāng)前元素的基礎(chǔ)上構(gòu)建引用。
- DataContext:如果沒(méi)有使用Source或RelativeSource屬性指定源,WPF就從當(dāng)前元素開(kāi)始在元素樹(shù)中向上查找。檢查每個(gè)元素的DataContext屬性,并使用第一個(gè)非空的DataContext屬性。
Source屬性
Source屬性非常簡(jiǎn)單。唯一的問(wèn)題是為了進(jìn)行綁定,需要具有數(shù)據(jù)對(duì)象。有多種方法獲取數(shù)據(jù)對(duì)象??蓮馁Y源中提取數(shù)據(jù)對(duì)象,可通過(guò)編寫(xiě)代碼生成數(shù)據(jù)對(duì)象,也可在數(shù)據(jù)提供程序的幫助下獲取數(shù)據(jù)對(duì)象。
最簡(jiǎn)單的選擇是將Source屬性指向一些已經(jīng)準(zhǔn)備好了的靜態(tài)對(duì)象。如,使用來(lái)自.NET類(lèi)庫(kù)的組件:
<TextBlock Text="{Binding Source={x:Static SystemFonts.IconFontFamily},Path=Source}"></TextBlock>
這個(gè)綁定表達(dá)式獲取由靜態(tài)屬性SystemFonts.IconFontFamily提供的FontFamily對(duì)象。注意需要借助靜態(tài)標(biāo)記擴(kuò)展Static。
綁定到先前作為資源創(chuàng)建的對(duì)象。如,標(biāo)記創(chuàng)建指向Calibri字體的FontFamily對(duì)象:
<Window.Resources> <FontFamily x:Key="CustomFont">Calibri</FontFamily> </Window.Resources>
TextBlock元素會(huì)被綁定到該資源:
<TextBlock Text="{Binding Source={StaticResource CustomFont}, Path=Source}"></TextBlock>
RelativeSource屬性
通過(guò)RelativeSource屬性可根據(jù)相對(duì)目標(biāo)對(duì)象的關(guān)系指向源對(duì)象。例如,可使用RelativeSource屬性將元素綁定到自身或其父元素。RelativeSource對(duì)象使用FindAncestor模式,該模式告知查找到元素樹(shù)直到發(fā)現(xiàn)AncestorType屬性定義的元素類(lèi)型。
<TextBlock> <TextBlock.Text> <Binding Path="Title"> <Binding.RelativeSource> <RelativeSource Mode="FindAncestor" AncestorType="{x:Type Window}"/> </Binding.RelativeSource> </Binding> </TextBlock.Text> </TextBlock>
編寫(xiě)綁定更常用的方法是使用Binding和RelativeSource標(biāo)記擴(kuò)展,將其合并到一個(gè)字符串種,如下所示:
<TextBlock Text="{Binding Path=Title, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}"> </TextBlock>
RelativeSourceMode 枚舉值
名稱(chēng) | 說(shuō)明 |
---|---|
self | 表達(dá)是綁定到同一元素的另一個(gè)屬性上 |
FindAncestor | 表達(dá)式綁定到父元素 |
PreviousData | 表達(dá)式綁定到數(shù)據(jù)綁定列表的前一個(gè)數(shù)據(jù)項(xiàng)。在列表元素中會(huì)使用到這種模式 |
TemplateParent | 表達(dá)式綁定到應(yīng)用模板的元素。只有當(dāng)綁定位于控件模板或數(shù)據(jù)模板內(nèi)部時(shí),這種模式才能工作 |
DataContent屬性
在某些情況下,會(huì)將大量元素綁定到同一個(gè)對(duì)象。
可使用和設(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元素綁定的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
基于C#實(shí)現(xiàn)網(wǎng)頁(yè)爬蟲(chóng)
這篇文章主要為大家詳細(xì)介紹了基于C#實(shí)現(xiàn)網(wǎng)頁(yè)爬蟲(chóng)的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-03-03C#如何打開(kāi)選擇文件對(duì)話(huà)框和選擇目錄對(duì)話(huà)框
這篇文章主要介紹了C#如何打開(kāi)選擇文件對(duì)話(huà)框和選擇目錄對(duì)話(huà)框問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-07-07詳解C#應(yīng)用程序如何實(shí)現(xiàn)多屏顯示
這篇文章主要為大家詳細(xì)介紹了C#如何實(shí)現(xiàn)把主屏運(yùn)行程序中多個(gè)窗體移動(dòng)到各個(gè)擴(kuò)展屏幕位置顯示,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2024-05-05C#使用泛型方法設(shè)計(jì)實(shí)現(xiàn)單向鏈表詳解
這篇文章主要為大家詳細(xì)介紹了C#如何使用泛型方法設(shè)計(jì)實(shí)現(xiàn)一個(gè)單向鏈表,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2024-02-02C#實(shí)現(xiàn)Nginx平滑加權(quán)輪詢(xún)算法
這篇文章主要為大家詳細(xì)介紹了C#實(shí)現(xiàn)Nginx平滑加權(quán)輪詢(xún)算法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-07-07在C#中如何使用ResNet50v2進(jìn)行圖像識(shí)別
ONNX?運(yùn)行時(shí)推理可以實(shí)現(xiàn)更快的客戶(hù)體驗(yàn)和更低的成本,支持來(lái)自深度學(xué)習(xí)框架如?PyTorch和TensorFlow/Keras以及經(jīng)典機(jī)器學(xué)習(xí)庫(kù)如?scikit-learn、LightGBM、XGBoost?等的模型,這篇文章主要介紹了在C#中如何使用ResNet50v2進(jìn)行圖像識(shí)別,需要的朋友可以參考下2024-07-07