如何使用WPF触发器为标签项设置鼠标移动事件?

时间:2009-11-07 23:43:04

标签: wpf animation mouseevent tabitem event-triggers

我已经覆盖了tabitem模板并创建了我自己的自定义样式。但是,我不确定如何为鼠标悬停事件编写事件触发器。


对于迟到的回复感到抱歉,我没有收到评论通知(也许这应该更改?)。 好的,我会尝试进一步解释。我没有添加评论,因为我需要发布示例代码。 假设你有一个控制,任何控制。 假设您还定义了许多画笔作为资源。 所以:

<LinearGradientBrush x:Key="NormalGradientBrush">
    <GradientStop Color="Black" Offset="0" />
    <GradientStop Color="Red" Offset="1" />
</LinearGradientBrush>

<LinearGradientBrush x:Key="NormalForeground">
    <GradientStop Color="Black" Offset="0" />
    <GradientStop Color="Gray" Offset="1" />
</LinearGradientBrush>

<LinearGradientBrush x:Key="MouseOverGradientBrush">
    <GradientStop Color="Red" Offset="0" />
    <GradientStop Color="Green" Offset="0.2" />
    <GradientStop Color="Black" Offset="1" />
</LinearGradientBrush>

<RadialGradientBrush x:Key="MouseOverForeground" GradientOrigin="0.3,0.5">
    <GradientStop Color="Gray" Offset="0" />
    <GradientStop Color="Black" Offset="1" />
</RadialGradientBrush >

现在假设你有标签项控件:

<LinearGradientBrush x:Key="MouseOverGradientBrush">
    <GradientStop Color="Black" Offset="0" />
    <GradientStop Color="Red" Offset="1" />
</LinearGradientBrush>

<Style x:Key="StyleTabItem"
       TargetType="{x:Type TabItem}">
    <Setter Property="Foreground"
            Value="{StaticResource NormalForeground}" />
    <Setter Property="BorderBrush"
            Value="Black" />
    <Setter Property="Background"
            Value="{StaticResource NormalGradientBrush}" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type TabItem}">
                <Grid SnapsToDevicePixels="true">
                    <Border x:Name="Bd"
                            Background="{TemplateBinding Background}"
                            BorderBrush="{TemplateBinding BorderBrush}"
                            BorderThickness="1,1,1,0"
                            Padding="{TemplateBinding Padding}">
                        <ContentPresenter x:Name="Content"
                        HorizontalAlignment="Center"
                        VerticalAlignment="Center"
                        SnapsToDevicePixels="True"
                        ContentSource="Header"
                        RecognizesAccessKey="True" />
                    </Border>
                </Grid>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsMouseOver"
                             Value="true">
                        // what here?
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

所以问题是,我怎么能告诉wpf在MouseOver事件中从当前画笔到MouseOverGradientBrush以及从当前前景到MouseOverForeground执行3秒动画? 我在例子中看到你通过逐个改变渐变偏移来做到这一点。我现在想要那个。它增加了代码的大小,最终可能会非常混乱。除了刷子可能具有不同数量的偏移或者一个可以是线性的而另一个可以是径向的。 我希望这更清楚。

5 个答案:

答案 0 :(得分:2)

这应该有效。我拿出了一堆你必须帮助简化事情的触发器。如果你使用它并需要添加更多功能,请告诉我,我们可以从那里构建它。

我还用静态颜色替换了您的资源引用。如果您将它们更改回资源并且它停止工作,那么资源所处的位置就会出现问题。

<LinearGradientBrush x:Key="MouseOverGradientBrush">
        <GradientStop Color="Black" Offset="0" />
        <GradientStop Color="Red" Offset="1" />
    </LinearGradientBrush>

 <Style x:Key="StyleTabItem"
           TargetType="{x:Type TabItem}">
        <Setter Property="Foreground"
                Value="{DynamicResource ForegroundGradient}" />
        <Setter Property="BorderBrush"
                Value="Black" />
        <Setter Property="Background"
                Value="Yellow" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type TabItem}">
                    <Grid SnapsToDevicePixels="true">
                        <Border x:Name="Bd"
                                Background="{TemplateBinding Background}"
                                BorderBrush="{TemplateBinding BorderBrush}"
                                BorderThickness="1,1,1,0"
                                Padding="{TemplateBinding Padding}"
                                CornerRadius="2,2,2,2">
                            <ContentPresenter x:Name="Content"
                                              HorizontalAlignment="{Binding HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"
                                              VerticalAlignment="{Binding VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"
                                              SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
                                              ContentSource="Header"
                                              RecognizesAccessKey="True" />
                        </Border>
                    </Grid>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsMouseOver"
                                 Value="true">
                            <Setter Property="Background"
                                    TargetName="Bd"
                                    Value="{StaticResource MouseOverGradientBrush}" />
                        </Trigger>
                        <Trigger Property="IsSelected"
                                 Value="true">
                            <Setter Property="Panel.ZIndex"
                                    Value="1" />
                            <Setter Property="Background"
                                    TargetName="Bd"
                                    Value="Cyan" />
                            <Setter Property="BorderBrush"
                                    TargetName="Bd"
                                    Value="Pink" />
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

答案 1 :(得分:1)

使用事件触发器的最佳解决方案是使用Expression Blend。它带有一种创建触发器的直观方式。

答案 2 :(得分:1)

感谢您的所有回复。我的触发器工作正常。我只是不能给它们制作动画。我有一个更简单的使用VisualStateManager在Silverlight中执行此操作,我不确定如何在WPF中完成此操作。

我正在提供我的样本,因为表达式混合为tabitem生成了模板的副本。

    <Style x:Key="StyleTabItem" TargetType="{x:Type TabItem}">
    <Setter Property="FocusVisualStyle" Value="{StaticResource TabItemFocusStyle}"/>
    <Setter Property="Foreground" Value="{DynamicResource ForegroundGradient}"/>
    <Setter Property="BorderBrush" Value="{StaticResource TabItemGradientBrushUnselected}"/>
    <Setter Property="Background" Value="{StaticResource TabItemBorderBrushUnselected}"/>
    <Setter Property="Padding" Value="6,1,6,1"/>  
    <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
    <Setter Property="VerticalContentAlignment" Value="Stretch"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type TabItem}">
                <ControlTemplate.Resources>
                    <Storyboard x:Key="Storyboard1">
                        <DoubleAnimation
                                Storyboard.TargetName="Bd" 
                                Storyboard.TargetProperty="BorderBrush.GradientStops[0].Offset"
                                Duration="00:00:00.3"/>
                    </Storyboard>
                </ControlTemplate.Resources>
                <Grid SnapsToDevicePixels="true">
                    <Border x:Name="Bd" 
                    Background="{TemplateBinding Background}" 
                    BorderBrush="{TemplateBinding BorderBrush}" 
                    BorderThickness="1,1,1,0" 
                    Padding="{TemplateBinding Padding}"
                    CornerRadius="2,2,2,2">
                        <ContentPresenter x:Name="Content" 
                        HorizontalAlignment="{Binding HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" 
                        VerticalAlignment="{Binding VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" 
                        SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" 
                        ContentSource="Header" 
                        RecognizesAccessKey="True"/>
                    </Border>
                </Grid>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsMouseOver" Value="true">
                        <Trigger.EnterActions>
                            <BeginStoryboard Storyboard="{StaticResource Storyboard1}"/>
                        </Trigger.EnterActions>
                        <Setter Property="Background" TargetName="Bd" Value="{StaticResource MouseOverGradientBrush}"/>
                    </Trigger>
                    <Trigger Property="Selector.IsSelected" Value="False"/>
                    <Trigger Property="IsSelected" Value="true">
                        <Setter Property="Panel.ZIndex" Value="1"/>
                        <Setter Property="Background" TargetName="Bd" Value="{StaticResource TabItemGradientBrushSelected}"/>
                        <Setter Property="BorderBrush" TargetName="Bd" Value="{StaticResource TabItemBorderBrushSelected}"/>
                    </Trigger>
                    <MultiTrigger>
                        <MultiTrigger.Conditions>
                            <Condition Property="IsSelected" Value="false"/>
                            <Condition Property="IsMouseOver" Value="true"/>
                        </MultiTrigger.Conditions>
                        <Setter Property="BorderBrush" TargetName="Bd" Value="{StaticResource TabItemMouseOverGradientBorder}"/>
                    </MultiTrigger>
                    <MultiTrigger>
                        <MultiTrigger.Conditions>
                            <Condition Property="IsSelected" Value="true"/>
                            <Condition Property="TabStripPlacement" Value="Top"/>
                        </MultiTrigger.Conditions>
                        <Setter Property="Margin" Value="-2,0,-2,0"/>
                        <Setter Property="Margin" TargetName="Content" Value="0,0,0,1"/>
                    </MultiTrigger>
                    <Trigger Property="IsEnabled" Value="false">
                        <Setter Property="Background" TargetName="Bd" Value="{DynamicResource DisabledGradientBrush}"/>
                        <Setter Property="BorderBrush" TargetName="Bd" Value="{DynamicResource DisabledGradientBorder}"/>
                        <Setter Property="Foreground" Value="{DynamicResource DisabledForeground}"/>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

我只想做(开始)是在鼠标悬停时将bd的背景从当前值(无论是什么)更改为mouseover = true触发器(MouseOverGradientBrush)中的值。上面的代码有什么问题,动画不起作用?我已经使用了表达混合我所能...

答案 3 :(得分:0)

答案 4 :(得分:0)

如果您真的想使用EventTrigger,可以这样做

<Style x:TargetType="TabItem">
    <Style.Triggers>
        <EventTrigger RoutedEvent="MouseOver">
          <BeginStoryboard>
            ....
          </BeinStoryboard>
        </EventTrigger>
    </Style.Triggers>
</Style>

在大多数情况下如果我正在进行简单,离散的值更改,我将在IsMouseOver属性更改时触发的Property触发器中执行此操作,而不是需要动画的EventTrigger

<Trigger Property="IsMouseOver" Value="True">
    <Setter Property="Foo" Value="Bar" />
</Trigger>