問題描述
我有一個數據對象用于包含支持 INotifyPropertyChanged
和 IDataErrorInfo
的 UI 數據.最初,我將所有 UI 控件顯示在一個大型 WPF 應用程序中,并且很高興看到通過這種自定義樣式標記的錯誤:
I have a data object used to contain my UI data that supports INotifyPropertyChanged
and IDataErrorInfo
. Originally I had all of the UI controls displaying in one big WPF application and was happily seeing errors flagged via this custom style:
<!-- Set error style for textboxes -->
<Style x:Key="txtBoxErrStyle" TargetType="{x:Type TextBox}">
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="True">
<Setter Property="ToolTip"
Value="{Binding RelativeSource={x:Static RelativeSource.Self},
Path=(Validation.Errors)[0].ErrorContent}" />
</Trigger>
</Style.Triggers>
<Setter Property="Validation.ErrorTemplate">
<Setter.Value>
<ControlTemplate>
<DockPanel DockPanel.Dock="Right">
<AdornedElementPlaceholder />
<Image Source="Error.png"
Height="16"
Width="16"
ToolTip="{Binding Path=AdornedElement.ToolTip, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Adorner}}}" />
</DockPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
我今天正在重新組織程序,并決定將各種 UI 控件分布在 TabControl
的幾頁上.我為此使用的結構布局是:
I was reorganizing the program today and decided to distribute the various UI controls over several pages of a TabControl
. The structure layout I am using for this is:
<tabcontrol>
<tabitem>
<AdornerDecorator>
[.. various Stack Panels, Groups and UI controls moved from original layout ..]
</AdornerDecorator>
</tabItem>
<tabitem>
<AdornerDecorator>
[.. various Stack Panels, Groups and UI controls moved from original layout ..]
</AdornerDecorator>
</tabItem>
...
</tabcontrol>
(我正在使用 AdornerDecorator
,正如我在之前的程序中所經歷的那樣,交換標簽頁時錯誤樣式沒有被重新呈現.我不記得我在哪里看到的,但它確實有幫助我出去.)
(I am using the AdornerDecorator
as I had experienced in a previous program the error style not being re-rendered when swapping tab pages. I can't remember where I saw this but it did help me out.)
現在當我啟動我的程序時,錯誤樣式正確呈現在程序啟動時打開的 TabItem
上,但沒有正確呈現在另一個(隱藏的)TabItem
s.當我選擇(并顯示)其中一個 TabItem
時,會設置錯誤樣式的工具提示,但不會顯示錯誤圖標圖像.
Now when I start my program the error style correctly renders on the TabItem
that is open when the program starts, but does not correctly render on the other (hidden) TabItem
s. When I select (and reveal) one of those TabItem
s the tool-tip of the error style is set, but the error icon image is not displayed.
我還測試了刪除自定義樣式并恢復為文本框的默認 WPF 錯誤樣式,我仍然得到類似的行為,即隱藏的 TabItem
上的控件周圍沒有紅色框當程序打開時.
I also tested removing the custom style and revert back to the default WPF error style for textboxes and I still get a similar behaviour, i.e. no red box around the control on the TabItem
s that are hidden when the program opens.
所以我似乎完全錯過了阻止錯誤樣式正確呈現的東西,而不是打開的選項卡項.有什么想法嗎?
So it seems that I am totally missing something that is stopping the error styles from correctly rendering on other than the open tab Item. Any ideas?
編輯 9 月 3 日 更改了描述以支持更好地理解我所看到的內容
Edit Sep 3 Changed description to support a better understanding of what I have seen
談 2014 年的似曾相識
現在是 2014 年 11 月,今天我遇到了這個愚蠢的 WPF 問題,錯誤模板未顯示在選項卡控制器中顯示的項目上.我腦海中的某件事表明我以前見過這個問題.于是我用谷歌搜索,首先彈出的是我自己 2009 年的問題!
It's November 2014 and today I had this stupid WPF problem with error templates not showing up on items presented in a tab controller. Something in the back of my mind suggests that I have seen this problem before. So I google, and the first thing that pops up is my own question from 2009!
這次我看到了我上次解決問題后添加的來自 dkl 的評論.所以我嘗試了他的方式并使用了這個解決方案(效果很好,我不需要在我的選項卡控件上撒上 Adorner 控件):
This time I see the comment from dkl which was added after I solved things the last time around. So I tried it his way and used this solution (which worked well and I didn't need to sprinkle an Adorner control over my tab controls):
<Style x:Key="TextBoxErrorStyle" TargetType="TextBox">
<Style.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="Validation.HasError" Value="True" />
<Condition Property="IsVisible" Value="True" />
</MultiTrigger.Conditions>
<Setter Property="Validation.ErrorTemplate">
<Setter.Value>
<ControlTemplate>
<DockPanel LastChildFill="True">
<TextBlock DockPanel.Dock="Right"
Foreground="Red"
FontSize="14pt"
Margin="-15,0,0,0" FontWeight="Bold">*
</TextBlock>
<Border BorderBrush="Red" BorderThickness="2">
<AdornedElementPlaceholder Name="controlWithError"/>
</Border>
</DockPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="ToolTip"
Value="{Binding RelativeSource={x:Static RelativeSource.Self}, Path=(Validation.Errors).CurrentItem.ErrorContent}" />
</MultiTrigger>
</Style.Triggers>
</Style>
推薦答案
(我正在使用 AdornerDecorator在以前的計劃中經歷過錯誤樣式沒有被重新渲染交換標簽頁時.我不能記得我在哪里看到的,但確實如此幫幫我)
(I am using the AdornerDecorator as I had experienced in a previous program the error style not being re-rendered when swapping tab pages. I can't remember where I saw this but it did help me out)
大概這個非常重要的提示來自 Karl Shifflets 博客,至少他在討論同一個主題:WPF 驗證錯誤消失切換 TabItems 時 TabControl 內部.
Presumably this indeed important tip originates from Karl Shifflets blog, at least he's addressing the same topic: WPF Validation Errors Disappear Inside TabControl When Switching TabItems.
鑒于此,您的問題可能只是相關的,即上面的提示/代碼確保有一個專用的 AdornerLayer
現在用于每個選項卡項,因為切換選項卡時父元素的裝飾層會被丟棄.這個專用的裝飾層似乎仍然需要一些特殊處理,例如問題 WPF ErrorTemplate visible什么時候不專注?這基本上是在處理你的問題.因此,我建議您將后者的概述解決方案與您的風格相結合并擴展,并嘗試以下方法(盡管目前尚未測試代碼):
Given this your issue might just be related, i.e. the tip/code above ensures there is a dedicated AdornerLayer
for every tab item now, as the adorner layer of the parent element is discarded when you switch tabs. This dedicated adorner layer appears to still require some special treatment though, see for example question WPF ErrorTemplate visible when not focused? which is basically dealing with your issue upside down. Consequently I'd suggest you combine and expand the outlined solution for the latter with your style and try the following (untested code as of now though):
<Style x:Key="ErrorTemplate" TargetType="{x:Type TextBox}">
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="True">...</Trigger>
<Trigger Property="IsVisible" Value="false">
<Setter Property="Validation.ErrorTemplate" Value="{x:Null}"/>
</Trigger>
<Trigger Property="IsVisible" Value="true">
<Setter Property="Validation.ErrorTemplate">
<Setter.Value>...</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
請參閱我關于您更新 單選按鈕錯誤樣式 的評論,它也嘗試類似解決您可能的相關問題;你真的在那里嘗試過我的建議嗎?
See my comment regarding your update of Radio Button Error Style too, which tries to similarly address your likely related question; have you actually tried my suggestion there?
有關裝飾器架構的更多詳細信息,請參閱裝飾器概述.
See Adorners Overview for more details on the adorner architecture.
這篇關于WPF 錯誤樣式僅在選項卡控件的可見選項卡上正確呈現的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!