WPF样式的错误仅被正确渲染选项卡控件的可视标签 [英] WPF Error Styles only being rendered properly on visible tab of a tab control

查看:199
本文介绍了WPF样式的错误仅被正确渲染选项卡控件的可视标签的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经习惯了包含支持 INotifyPropertyChanged的 IDataErrorInfo的我的UI数据的数据对象。我本来都在一个大的WPF应用程序中显示的UI控件,并愉快地见状通过这种自定义样式标记错误:

 < ;! - 为文本框设置错误样式 - > 
<风格X:键=txtBoxErrStyle的TargetType ={X:TextBox类型}>
< Style.Triggers>
<触发属性=Validation.HasErrorVALUE =真>
< setter属性=工具提示
值={绑定的RelativeSource = {X:静态RelativeSource.Self}
路径=(Validation.Errors)[0] .ErrorContent} />
< /触发>
< /Style.Triggers>

< setter属性=Validation.ErrorTemplate>
< Setter.Value>
<&控件模板GT;
< D​​ockPanel中DockPanel.Dock =右>
< AdornedElementPlaceholder />
<图像源=Error.png
高度=16
WIDTH =16
工具提示={绑定路径= AdornedElement.ToolTip,的RelativeSource = {的RelativeSource模式= FindAncestor,AncestorType = {X:类型的Adorner}}}/>
< / DockPanel中>
< /控件模板>
< /Setter.Value>
< /二传手>
< /样式和GT;



我是重组计划今天,并决定在一个几页分发的各种UI控件的TabControl 。我使用这个结构布局是:



 <&TabControl的GT; 
<&TabItem的GT;
< AdornerDecorator>
[从原来的布局移动..各种堆栈面板,组和UI控件..]
< / AdornerDecorator>
< / TabItem的>
<&TabItem的GT;
< AdornerDecorator>
[从原来的布局移动..各种堆栈面板,组和UI控件..]
< / AdornerDecorator>
< / TabItem的>


< / TabControl的>



(我用的是 AdornerDecorator 我经历过之前的程序错误的风格不被重新呈现交换标签页时,我不记得在那里我看到了这一点,但它确实帮助我。)



现在,当我开始我的程序错误样式正确地呈现在 TabItem的即打开程序启动时,但不会对其他(隐藏)<$ C正确呈现$ C> TabItem的秒。当我选择(并揭示)其中的一个 TabItem的 S中的错误样式的工具提示设置,但不显示错误图标的图像。



我还测试删除自定义样式,并恢复到默认的WPF错误样式文本框和我仍然得到了类似的行为,即在控制周围的 TabItem的 S上的程序打开时是隐藏的。



如此看来,我完全失去了一些东西是从正确停止错误的风格在渲染以外的开放标签项目。任何想法?



修改09月03日修改描述,以支持更好地理解我所看到的。



谈论似曾相识,2014年



这是2014年11月,今天我有这个愚蠢的WPF问题,错误的模板没有显示出来在一个选项卡控制器提出的项目。东西在我的脑海表明,我以前见过这个问题。所以,我谷歌,并在弹出的第一件事就是从2009年我自己的问题!



这一次,我看到DKL后,我解决的事情最后再加入评论阵子。所以,我试了一下他的方式,并使用该解决方案(其中运作良好,我不需要在我的标签控件洒装饰器控制):

 <风格X:键=TextBoxErrorStyle的TargetType =文本框> 
< Style.Triggers>
< MultiTrigger>
< MultiTrigger.Conditions>
<条件属性=Validation.HasErrorVALUE =真/>
<条件属性=可见性VALUE =真/>
< /MultiTrigger.Conditions>
< setter属性=Validation.ErrorTemplate>
< Setter.Value>
<&控件模板GT;
< D​​ockPanel中LastChildFill =真>
< TextBlock的DockPanel.Dock =右
=前景红
字号=14pt
保证金= - 15,0,0,0粗细= 大胆> *
< / TextBlock的>
< BORDER = BorderBrush红了borderThickness =2>
< AdornedElementPlaceholder NAME =controlWithError/>
< /边框>
< / DockPanel中>
< /控件模板>
< /Setter.Value>
< /二传手>
< setter属性=工具提示
值={绑定的RelativeSource = {X:静态RelativeSource.Self},路径=(Validation.Errors).CurrentItem.ErrorContent}/>
< / MultiTrigger>
< /Style.Triggers>
< /样式和GT;


解决方案

(我用交换标签页时,我
在以前的节目
错误风格经历过AdornerDecorator没有被重新呈现
我不能
记得在那里我看到了这一点,但它// karlshifflett:没有
帮我)




据推测,这的确是重要的秘诀来自的Karl Shifflets博客,至少他的寻址同一主题: WPF验证错误消失TabControl的内部切换时的TabItems 的。



有鉴于此您的问题可能只是相关,即上面的尖/代码确保有专门的 AdornerLayer 为每个选项卡项目现在,作为父元素的装饰器层被丢弃,当你切换标签。这种专用的装饰器层似乎仍然需要一些特殊的处理虽然,例如见问题 WPF ErrorTemplate可见当不集中?这基本上是与您的问题处理倒挂。因此我建议你结合起来,扩大后者的解决方案概述与你的风格和尝试以下操作(未测试的代码以现在虽然):

 <风格X:键=ErrorTemplate的TargetType ={X:TextBox类型}> 
< Style.Triggers>
<触发属性=Validation.HasErrorVALUE =真> ...< /触发>
<触发属性=可见性VALUE =false的>
< setter属性=Validation.ErrorTemplateVALUE ={X:空}/>
< /触发>
<触发属性=可见性VALUE =真正的>
< setter属性=Validation.ErrorTemplate>
< Setter.Value> ...< /Setter.Value>
< /二传手>
< /触发>
< /Style.Triggers>
< /样式和GT;

请参阅有关您的单选按钮错误样式过,它试图解决同样的可能相关的问题;让你真正尝试我的建议呢?



请参阅装饰器概述<​​/a>关于装饰器体系结构的更多细节。


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>

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>

(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.)

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) TabItems. When I select (and reveal) one of those TabItems the tool-tip of the error style is set, but the error icon image is not displayed.

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 TabItems 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?

Edit Sep 3 Changed description to support a better understanding of what I have seen

Talk about Déjà vu in 2014

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!

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>

解决方案

(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)

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.

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样式的错误仅被正确渲染选项卡控件的可视标签的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆