在XAML中使用触发器的问题

时间:2011-07-18 19:08:21

标签: wpf xaml triggers

在下面的代码中,当鼠标位于网格上方时,网格的Background预计为红色,但不会按预期执行。

<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)相关联。

此外,在代码段的上方,如果GridButton替换,则这两个代码都不会按预期执行。


更新:添加有关此问题的按钮案例

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

1 个答案:

答案 0 :(得分:3)

问题是你的Grid有一个空背景,所以鼠标命中测试看不到它。如果您将背景设置为透明,那么它将像您将其设置为绿色时一样可以进行测试。

可以找到更多信息here

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

这与属性优先权无关。对于网格来说,这只是你的网格不能被击中测试的问题。因此它的IsMouseOver不会设置为true,除非它具有非null背景(或者呈现某些内容的子项)。

您可以在此处查看优先级:

<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,你有这样的东西:

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

在这种情况下,有两个背景属性:控件模板中的按钮和边框。默认情况下,Border的Background属性由Border使用,但当鼠标悬停时,它使用Red刷子。此时,Button的Background属性的值设置为什么并不重要。