WPF中关于对前台Xaml中Triggers的一些重要思考。

    今天在做一个小Demo的时候碰到了一个比较奇怪的问题,就是其中一个Trigger始终无法执行,就是当Popup控件关闭的时候不能触发这个状态,首先贴一下具体的代码和展现的具体效果。

              VerticalContentAlignment="Center" Opacity="0.6" >
                
                    
                        
                            
                                
                            
                                                IsOpen="{Binding IsChecked,RelativeSource={RelativeSource TemplatedParent}}"
                                   PlacementTarget="{Binding ElementName=BG}">                                
                                
                                    
                                    
                                    
                                    
                                
                            
                        
                        
                                                         
                                                                
                            
                            
                                
                            
                        
                    
                
                       

  

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

WPF中关于对前台Xaml中Triggers的一些重要思考。_第1张图片

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

                                               
                                                                
                              

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

WPF中关于对前台Xaml中Triggers的一些重要思考。_第2张图片    也就是说第二个Trigger又将Border的背景设置成灰色了。首先看看第二个Trigger的具体内容:

             
              
            

  

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

            
              
            

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

WPF中关于对前台Xaml中Triggers的一些重要思考。_第3张图片

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

               
                  
                                
                                                        
                                                         
                                                                
                             
                                                

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

 

转载于:https://www.cnblogs.com/seekdream/p/5395213.html

你可能感兴趣的:(WPF中关于对前台Xaml中Triggers的一些重要思考。)