簡體   English   中英

XAML“有條件”綁定

[英]XAML “Conditional” Binding

我有一個DataTrigger附加到TextBlock的樣式,定義如下:

<DataTrigger Binding="{Binding Path=Link, Converter={StaticResource HasContentConverter}}" Value="True">
    <Setter Property="TextDecorations" Value="Underline" />
    <Setter Property="Cursor" Value="Hand" />
</DataTrigger>

我遇到的問題是我有多個對象最終使用這種風格,其中一些包含“鏈接”屬性,而其中一些則沒有。 只要系統遇到沒有的對象,它就會在輸出窗口中輸出以下錯誤:

BindingExpression路徑錯誤:'對象'''DataRowView'(HashCode = 53681904)'上找不到'鏈接'屬性。 BindingExpression:路徑=鏈接; DataItem ='DataRowView'(HashCode = 53681904); target元素是'TextBlock'(Name =''); target屬性是'NoTarget'(類型'對象')

這是預期的行為,但是我想知道是否有辦法告訴XAML中的處理器僅在“鏈接”屬性存在時才應用(即在嘗試綁定之前檢查屬性,或者某些其他方法沒有打印錯誤)。 這可能嗎?

開箱即用,直接無法實現。

不是開箱即用:您可以編寫自己的BindingExtension,其行為類似於:如果prop存在則綁定,否則忽略。 你也可以,khem,關閉報告綁定錯誤,但當然通常不需要。

不直接:您可以創建某種類型的附加屬性,然后設置此類屬性而不是設置綁定。 您的屬性設置器將附加到datacontext-changes並檢查對象和可視組件在它們四處飛行時是否設置綁定。

不直接#2:您可以嘗試“層次化”樣式和觸發器。 如您所知,Trigger有一個條件。 將你的風格分為兩部分:第一部分是不需要“保護”的普通風格,第二部分包含依賴於“Blargh”屬性的特征。 將第一個樣式設置為默認/正常。 現在創建一個名為“DefinesBlargh”或“HasBlarghDefines”的只讀附加屬性,用於檢查目標對象的datacontext是否實際具有此屬性。 現在添加第一個樣式的觸發器,檢測樣式控件是否具有“HasBlarghDefined”等於“true”,並在觸發器的動作中...

......這就是問題所在。 該怎么辦? 你不能再將樣式替換為樣式的第二部分,因為它可能會刪除觸發器並反過來停用邏輯(它將是一次性)。 或者,由於嘗試在一次更新掃描中嘗試兩次更改樣式,它可能會崩潰。 我其實不知道會發生什么,但我感覺到“有異味”。 更重要的是,改為第二部分將簡單地抹去第一部分設置的常見事物。

所以,如果它實際上會運行並替換樣式,你必須確保保留原始觸發邏輯和第一個樣式的其余部分,我建議使用“樣式繼承”,即基於樣式property: http//wpftutorial.net/StyleInheritance.html也就是說,不要創建兩個獨立的部分,而是創建一個包含所有常見內容的“基礎部分”,以及基於第一個和第一個部分的“專用部分”。添加不安全的額外的東西。 現在動態地重新替換到專門的對應物是更合理的。

或者,如果你對布局有一些控制,你可以變得聰明:為什么要將兩種樣式應用於同一個組件? 在控件的某個外邊界上設置常規樣式並在其中放置額外的觸發器,然后讓觸發器將小的不安全的第二種樣式應用於控件。

如果你真的必須使用樣式的兩個部分准確地定位一個控件並且不能使用“基於”或者如果它根本不起作用等,你可以做另一個聰明的技巧:使用允許你定義樣式的MultiStyle將兩個/三個/ +其他樣式合並為一個,然后構建一個觸發器層次結構,如下所示:

multitrigger
   condition: HasBlarghDefined = TRUE
   condition: your own data condition
   setter: set style = multistyle of "generalpart" and "usnafepart"
multitrigger
   condition: HasBlarghDefined = FALSE
   condition: your own data condition
   setter: set style = just a generalpart

恕我直言,只需要工作。

編輯:忘記過關鍵鏈接: MultiStyle

所以我的最終解決方案是有一個基本的DataGrid類來實現相關的樣式,減去“Link”特定的數據觸發器。 然后我有了一個從我的基類派生的新DataGrid類,其代碼專門用於創建數據觸發器:

Binding binding = new Binding("Link");
binding.Converter = new MDTCommon.Converters.HasContentConverter();
DataTrigger trigger = new DataTrigger();
trigger.Binding = binding;
trigger.Value = true;
Setter setter1 = new Setter(TextBlock.TextDecorationsProperty, TextDecorations.Underline);
Setter setter2 = new Setter(TextBlock.CursorProperty, Cursors.Hand);
trigger.Setters.Add(setter1);
trigger.Setters.Add(setter2);
Style style = FindResource("DefaultStyleInQuestion") as Style;
style.Triggers.Add(trigger);

我能夠使用此方法,因為具有“鏈接”屬性的綁定對象僅用於我的派生DataGrid類。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM