GE:Imagination at work

[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!






posted on 2008-05-26 11:36 周银辉 阅读(1809) 评论(2)  编辑 收藏 所属分类: WPF

评论

#1楼  2008-05-27 11:36 傻样精英      

绑定好像很难用啊
我双向绑定了一个东西,使用了Converter。
第一个显示日期。第二个显示时间。如果我不修改时间的话,怎么就没有值呢。
而且我修改了时间,日期就是当日了,怎么跟第一显示被修改了的日期连成一个日期时间?   回复  引用  查看    

#2楼  2008-06-02 11:01 夕日含林 [未注册用户]

你是通过隐藏Grid来隐藏TextBox的吗?
如果直接设置TextBox的Visiblity属性,直接绑定到holder的Visibility可以隐藏ErrorTemplate   回复  引用    


标题  
姓名  
主页
Email (博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
"五向定位"职业成长路线公开课(上海、南京、大连)
Google站内搜索


相关链接:
 

导航

公告

<2008年5月>
27282930123
45678910
11121314151617
18192021222324
25262728293031
1234567

统计

搜索

 

常用链接

留言簿(83)

我参加的小组

我参与的团队

随笔分类(188)

随笔档案(174)

友情链接

积分与排名

最新随笔

阅读排行榜