zoukankan      html  css  js  c++  java
  • [WPF疑难]ErrorTemplate显示与隐藏问题

                               [WPF疑难]ErrorTemplate显示与隐藏问题
                                            周银辉
    1,问题描述:

    在为Binding提供验证模板时,我们需要使用一个ControlTemplate来为验证控件提供验证反馈,即是当验证失败时在被验证控件的旁边或外围提供一个具有明显视觉效果的UI元素以提醒用户(一个普遍的做法,比如文本框外围出现一个红色线框),这也就是传说中的Validation.ErrorTemplate。按照正常人的思维:ErrorTemplate(红色线框)的可见性应该随着被验证控件(文本框)的可见性的改变而动态改变。但目前事实并非如此,即便是用WPF默认的ErrorTemplate。这让人很抓狂,在用户看来这将是一个可笑而又弱智的错误。

    让用户输入点什么:


    出错了,显示一个红线框以提醒:


    点击Expander将文本框隐藏起来,当红线框依然存在:



    2,解决方案

    2.1 思路
    先看看我们的ErrorTemplate是如何编写的:
            <ControlTemplate x:Key="validationTemplate">
                <Border BorderBrush="Red"
                        BorderThickness="2" >
                    <AdornedElementPlaceholder x:Name="holder" />
                </Border>
            </ControlTemplate>
    其中AdornedElementPlaceholder 是一个占位符,表示修饰控件相对于ControlTemplate中其它元素所放置的位置(这个示例中用于文本框的占位),而Border则是我们的红线框。那么很自然地(这让我想起中学数学中的”同理可证、所以、显然“)我们可以将Border 的可见性与AdornedElementPlaceholder.AdornedElement(这里是我们文本框) 的可见性Binding起来而解决这个问题,的确如此

    2.2 容易写出的错误代码:
            <ControlTemplate x:Key="validationTemplate">
                <Border BorderBrush="Red"
                        BorderThickness="2"
                        Visibility="{Binding ElementName=holder,Path=AdornedElement.Visibility} >
                    <AdornedElementPlaceholder x:Name="holder" />
                </Border>
            </ControlTemplate>
    错误的原因是,Visiblity属性是不能向下传递的。意思是说:假设一个grid中包含一个textBox,开始时两者均可见(Visibility == Visibility.Visible),当将grid.Visibility设置为Hiden后其它时并不会影响textBox.Visibility,虽然textBox的确看不见了。

    2.3 正确的方式:
    事实上你应该根据UIElement.IsVisible属性来检测元素是否可见(只读属性),通过UIElement.Visibility 来设置元素的可见性。(虽然这让人感觉如此之混乱)

            <BooleanToVisibilityConverter x:Key="bvConverter" />

            <ControlTemplate x:Key="validationTemplate">
                <Border BorderBrush="Red"
                        BorderThickness="2"
                        Visibility="{Binding ElementName=holder,Path=AdornedElement.IsVisible, Converter={StaticResource bvConverter}}">
                    <AdornedElementPlaceholder x:Name="holder" />
                </Border>
            </ControlTemplate>

    Done!






  • 相关阅读:
    poj 3616 Milking Time
    poj 3176 Cow Bowling
    poj 2229 Sumsets
    poj 2385 Apple Catching
    poj 3280 Cheapest Palindrome
    hdu 1530 Maximum Clique
    hdu 1102 Constructing Roads
    codeforces 592B The Monster and the Squirrel
    CDOJ 1221 Ancient Go
    hdu 1151 Air Raid(二分图最小路径覆盖)
  • 原文地址:https://www.cnblogs.com/zhouyinhui/p/1207409.html
Copyright © 2011-2022 走看看