今天在做一个小Demo的时候碰到了一个比较奇怪的问题,就是其中一个Trigger始终无法执行,<Trigger Property="Popup.IsOpen" Value="False">就是当Popup控件关闭的时候不能触发<Setter TargetName="BG" Property="Background" Value="Gray" />这个状态,首先贴一下具体的代码和展现的具体效果。

    <CheckBox x:Name="label" HorizontalAlignment="Center" VerticalAlignment="Center"  FontSize="26" Content="场景列表" HorizontalContentAlignment="Center" 
          VerticalContentAlignment="Center" Opacity="0.6" >
<CheckBox.Template>
<ControlTemplate TargetType="{x:Type CheckBox}">
<Grid>
<Border x:Name="BG" Background="{TemplateBinding Control.Background}">
<ContentPresenter Content="{TemplateBinding ContentControl.Content}"></ContentPresenter>
</Border>
<Popup x:Name="MyPopup" Placement="Bottom" AllowsTransparency="True" PopupAnimation="Slide" StaysOpen="False"
                    IsOpen="{Binding IsChecked,RelativeSource={RelativeSource TemplatedParent}}"
PlacementTarget="{Binding ElementName=BG}">
<StackPanel>
<Button Content="按钮1" Width="100" Height="30" FontSize="16" Foreground="Teal"></Button>
<Button Content="按钮2" Width="100" Height="30" FontSize="16" Foreground="Teal"></Button>
<Button Content="按钮3" Width="100" Height="30" FontSize="16" Foreground="Teal"></Button>
<Button Content="按钮4" Width="100" Height="30" FontSize="16" Foreground="Teal"></Button>
</StackPanel>
</Popup>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="ToggleButton.IsChecked" Value="True">
<Setter TargetName="BG" Property="Background" Value="Red" />
</Trigger>
<Trigger Property="Popup.IsOpen" Value="False">
<Setter TargetName="BG" Property="Background" Value="Gray" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</CheckBox.Template>
</CheckBox>

  

  预期的效果是当我们点击该按钮时,弹出Pop并且,设置Border 的背景为红色,但实际情况下是当我们点击之后确实能够弹出Popup但是Border的背景却仍然为灰色。

按照我们的理解,当我们点击“场景列表”时,首先执行下面的Trigger,然后设置Border的背景为红颜色。

                  <Trigger Property="ToggleButton.IsChecked" Value="True">
<Setter TargetName="BG" Property="Background" Value="Red" />
</Trigger>

  但是结果是最终的背景色也为灰色,那么删除掉第二个Trigger时,又会有怎样的结果

    也就是说第二个Trigger又将Border的背景设置成灰色了。首先看看第二个Trigger的具体内容:

            <Trigger Property="Popup.IsOpen" Value="False"> 
              <Setter TargetName="BG" Property="Background" Value="Gray" />
            </Trigger>

  

    也就是但是Popup.IsOpen的值为False,但是 IsOpen="{Binding IsChecked,RelativeSource={RelativeSource TemplatedParent}}" IsOpen的值是绑定到CheckBox的               IsChecked属性的,但是IsChecked属性的值为true,这个是怎么回事,也就是说这个Popup.IsChecked属性使用的是默认值,并没有绑定到具体的PopUp控件上,最后我们查找到在进行定义Trigger属性的时候,有一个属性值就是SourceName这个是和TargetName是一对的,即绑定的源头,所以下面做了如下更改:

            <Trigger Property="Popup.IsOpen" Value="False" SourceName="MyPopup">
              <Setter TargetName="BG" Property="Background" Value="Gray" />
            </Trigger>

   这样再运行代码的时候,可以看到效果是可以出来的,也就是Popup.IsOpen属性确实是关联到MyPopup上面,下面就具体截图为证。

但是当我们调整两个Trigger的位置的时候,又可以正常执行。

              <ControlTemplate.Triggers>
              <Trigger Property="Popup.IsOpen" Value="False">
<Setter TargetName="BG" Property="Background" Value="Gray" />
</Trigger>
<Trigger Property="ToggleButton.IsChecked" Value="True">
<Setter TargetName="BG" Property="Background" Value="Red" />
</Trigger>
</ControlTemplate.Triggers>

  后来仔细想一下也是对的啊,首先WPF这种查找属性的机制都是基于可视化树向上查找的,当执行这两个Trigger的时候,如果先执行Property="ToggleButton.IsChecked"这个属性的时候,再向下执行第二个Trigger的时候如果没有指定SourceName属性,它会默认沿着视觉树向上查找,由于在CheckBox之上我们是找不到Popup控件的,所以它会使用默认值,所以才有了最开始的问题,所以在我们写Trigger的时候,第一个Trigger里面一定要写视觉树中比较底层的元素,然后一级一级往上写,这样我们就不会出现上面出现的各种莫名其妙的问题。第二种原则就是按照规范的写法为每一个Trigger都写上SourceName属性,这样无论先后顺序都可以执行下去的。这个是在定义Trigger的时候的两条基本原则,在使用时需要特别注意。

WPF中关于对前台Xaml中Triggers的一些重要思考。的更多相关文章

  1. WPF中动态加载XAML中的控件

    原文:WPF中动态加载XAML中的控件 using System; using System.Collections.Generic; using System.Linq; using System. ...

  2. WPF学习01:初始XAML浅析

    本文内容: 浅析WPF应用默认创建的XAML中元素.attributes. 新建WPF工程“HelloWPF”. 初始创建的主窗体XAML代码如下: <Window x:Class=" ...

  3. 《深入浅出WPF》学习总结之XAML标签语言一

    一.XMAL概览 1.XAML在桌面开发及富媒体网络程序的开发中扮演了HTML+CSS+JS的角色. 2.XAML可以将UI和逻辑代码分离,降低耦合度. 3.XAML是一种单纯的申明形语言 4.XAM ...

  4. 【C#】WPF的xaml中定义的Trigger为什么有时候会不管用,如Border的MouseOver之类的

    原文:[C#]WPF的xaml中定义的Trigger为什么有时候会不管用,如Border的MouseOver之类的 初学WPF,知道一些控件可以通过定义Style的Trigger改变要显示的样式,但是 ...

  5. VS编程,编辑WPF过程中,点击设计器中界面某一控件,在XAML中高亮突出显示相应的控件代码的设置方法。

    原文:VS编程,编辑WPF过程中,点击设计器中界面某一控件,在XAML中高亮突出显示相应的控件代码的设置方法. 版权声明:我不生产代码,我只是代码的搬运工. https://blog.csdn.net ...

  6. WPF绑定xaml中绑定对象需用属性表示,字段不可以绑定

    在练习WPF绑定时发现对象属性可以在XAML中绑定,但字段是不可以绑定: 比如: private Person person{get;set;}  可以绑定到XAML中,<TextBox Nam ...

  7. WPF中,怎样将XAML代码加载为相应的对象?

    原文:WPF中,怎样将XAML代码加载为相应的对象? 在前面"在WPF中,如何得到任何Object对象的XAML代码?"一文中,我介绍了使用System.Windows.Marku ...

  8. WPF中CAD control的XAML实现

    原文:WPF中CAD control的XAML实现     下面这个XAML文件是cad control里面最重要的一部分,使用Grid包含Viewport,Viewport中包括Camera和mod ...

  9. WPF中任意Object的XAML代码格式化输出

    原文:WPF中任意Object的XAML代码格式化输出 有时候,我们需要将WPF中的控件自身的XAML代码输出成文本,那么,我们可以使用System.Windows.Markup.XamlWriter ...

随机推荐

  1. flask_sqlalchemy中根据聚合分组后的结果进行排序,根据日期(datetime)按天分组

    from sqlalchemy import func, desc # 根据聚合查询总收入,按总收入逆序 s= db.session.query(TpOrders.room_type_id, (fun ...

  2. flask上传excel文件,无须存储,直接读取内容

    运行环境python3.6 import xlrd from flask import Flask, request app = Flask(__name__) @app.route("/& ...

  3. nginx之十三:搭建 nginx 反向代理用做内网域名转发

      user www www;worker_processes 1;error_log logs/error.log;pid logs/nginx.pid;worker_rlimit_nofile 6 ...

  4. [Micropython]TPYBoard v102 DIY照相机

    摄像头(CAMERA或WEBCAM)又称为电脑相机.电脑眼.电子眼等,是一种视频输入设备,被广泛的运用于视频会议,安防系统 .图像采集系统. 环境监控 .工业现场过程控制 等方面.本实验用TPYBoa ...

  5. SkylineGlobe TerraExplorer Pro 7.0 Web 控件版 第一行示例代码

    SkylineGlobe TerraExplorer Pro 7.0 是原生的64位应用程序,在Web端用插件方式开发的第一行示例代码如下: 常规代码,需要IE64位: <!DOCTYPE ht ...

  6. 【原创】分布式之elk日志架构的演进

    引言 好久没写分布式系列的文章了,最近刚好有个朋友给我留言,想看这方面的知识.其实这方面的知识,网上各种技术峰会的资料一抓一大把.博主也是凑合着写写.感觉自己也写不出什么新意,大家也凑合看看. 日志系 ...

  7. Django的路由层

    U RL配置(URLconf)就像Django 所支撑网站的目录.它的本质是URL与要为该URL调用的视图函数之间的映射表:你就是以这种方式告诉Django,对于客户端发来的某个URL调用哪一段逻辑代 ...

  8. 【RSYSLOG】The Property Replacer【转】

    最近在调整日志平台的日志格式,一下是RSYSLOG的 Property Replacer 说明.鉴于RSYSLOG官网略坑,转发一下,原地址忘记了- - ||| The property replac ...

  9. 无法从带有索引像素格式的图像创建graphics对象

    大家在用 .NET 做图片水印功能的时候, 很可能会遇到 “无法从带有索引像素格式的图像创建graphics对象”这个错误,对应的英文错误提示是“A Graphics object cannot be ...

  10. rest-framework的权限组件

    权限组件 写在开头: 首先要在models表中添加一个用户类型的字段: class User(models.Model): name=models.CharField(max_length=32) p ...