2011-07-18 67 views
3

在下面的代码中,当鼠标在网格,网格的Background预期为红色,但如预期它不执行的问题。使用触发器在XAML

<Grid> 
    <Grid.Style> 
    <Style TargetType="{x:Type Grid}"> 
     <Style.Triggers> 
      <Trigger Property="IsMouseOver" Value="True"> 
       <Setter Property="Background" Value="Red"/> 
      </Trigger> 
     </Style.Triggers> 
     </Style> 
    </Grid.Style> 
</Grid> 

但是,如果我加入了Setter使Background绿色,它会被正确执行。

<Grid> 
    <Grid.Style> 
    <Style TargetType="{x:Type Grid}"> 
     <Setter Property="Background" Value="Green"/><!-- at the former, added code--> 
     <Style.Triggers> 
      <Trigger Property="IsMouseOver" Value="True"> 
       <Setter Property="Background" Value="Red"/> 
      </Trigger> 
     </Style.Triggers> 
     </Style> 
    </Grid.Style> 
</Grid> 

我不知道为什么要这样,但你猜有用于设置Background,造成这一问题的优先级。这里是来自MSDN的Dependency Property Value Precedence,我理解该引用的优先级,但我无法将此问题与优先级(MSDN)相关联。

此外,在上面的代码片段中,如果将Grid替换为Button,则这两个代码将不会按预期执行。


更新:添加按钮的情况下这个问题

<Button> 
    <Button.Style > 
     <Style TargetType="{x:Type Button}"> 
      <Setter Property="Background" Value="Transparent"/> 
      <Style.Triggers> 
       <Trigger Property="IsMouseOver" Value="True"> 
        <Setter Property="Background" Value="Red"/> 
       </Trigger> 
      </Style.Triggers> 
     </Style> 
    </Button.Style> 
</Button> 

回答

3

的问题是你的网格有一个空的背景,所以它是不可见的鼠标点击测试。如果将背景设置为透明,则将其设置为绿色时可以进行检测。

更多信息,可以发现here

我想你的按钮,背景是正确初始化为透明。红色值仅显示几分之一秒。这是因为在Aero主题中(我在Windows 7上),Button的ControlTemplate使用自定义镶边来提供动画状态转换(即悬停等)。此自定义镶边元素使用内部画笔,并忽略背景属性。

此无关财产优先。对于网格来说,这只是你的网格不能被命中测试的问题。所以它的IsMouseOver不会被设置为true,除非它具有非空背景(或者呈现某物的子节点)。

你可以看到在优先这里的行动:

<Grid Background="Blue"> 
    <Grid.Style> 
     <Style TargetType="{x:Type Grid}"> 
      <Setter Property="Background" Value="Green"/> 
      <Style.Triggers> 
        <Trigger Property="IsMouseOver" Value="True"> 
         <Setter Property="Background" Value="Red"/> 
        </Trigger> 
       </Style.Triggers> 
     </Style> 
    </Grid.Style> 
</Grid> 

在上面,网格将永远是蓝作为具有最高优先级(即本地或#3)。红色(#6)优先于绿色(#8)。

在按钮的情况下,你有这样的事情:

<Button Background="Blue"> 
    <Button.Style> 
     <Style TargetType="{x:Type Button}"> 
      <Setter Property="Template"> 
       <Setter.Value> 
        <ControlTemplate TargetType="Button"> 
         <Border x:Name="border" Background="{TemplateBinding Background}"> 
          <ContentPresenter /> 
         </Border > 
         <ControlTemplate.Triggers> 
          <Trigger Property="IsMouseOver" Value="True"> 
           <Setter TargetName="border" Property="Background" Value="Red"/> 
          </Trigger> 
         </ControlTemplate.Triggers> 
        </ControlTemplate> 
       </Setter.Value> 
       </Setter> 
     </Style> 
    </Button.Style> 
</Button> 

在这种情况下,也有两种游戏背景属性:此按钮并在控制模板中的边界。默认情况下,按钮的背景属性由边框使用,但当鼠标悬停时,它使用红色画笔。此时,Button的Background属性的值设置为什么并不重要。

+0

如果你有多余的时间,请阅读http://wangmo.wordpress.com/2008/12/12/pitfall-with-using-triggers-in-style-and-controltemplate/。对不起,烦人。他/她提到这个问题是“对FrameworkElement的属性在样式覆盖setter方法或控件模板,因此,由制定者的任何变化不会带来实际的任何变化。”我无法确定哪个是正确的。要清楚,你认为Button Button有什么用?我会尽快更新我的问题。 –

+0

@jwJung - 是的,如果你明确地在像 CodeNaked

+0

通过您的努力,我越来越好地解决了这个问题。你让我保证吗?在[MSDN](http://msdn.microsoft.com/en-us/library/ms743230.aspx)的优先顺序中,“如果您明确指出...但这不适用于Grid。”意味着优先级3(本地值),因此由于优先级而改变颜色是不适用的。对于Button的情况,我的quetion的代码片段是优先级6(样式触发器),但由于TemplatedParent模板(优先级4)定义了Button的颜色(默认颜色:灰色?),所以Button的背景将不会更改为红色,即使一只老鼠在它上面。 –