1

我已经覆盖了 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 秒的动画?我在示例中看到您通过一一更改渐变的偏移量来做到这一点。我现在确实想要那个。它增加了代码的大小,最终可能会变得非常混乱。此外,笔刷可能有不同数量的偏移,或者一个可以是线性的,另一个可以是径向的。我希望这更清楚。

4

5 回答 5

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>
于 2009-11-12T15:46:55.760 回答
1

The best solution for using event triggers is to use Expression Blend. It comes with an intuitive way to create triggers.

于 2009-11-08T00:39:27.463 回答
1

感谢您的所有回复。我的触发器工作正常。我只是不能为它们设置动画。通过使用 VisualStateManager,我有一个更简单的 wat 在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)中的值。上面的代码有什么问题,动画不起作用?我已经尽我所能使用了表情混合......

于 2009-11-09T07:10:35.113 回答
0

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

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

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

<Trigger Property="IsMouseOver" Value="True">
    <Setter Property="Foo" Value="Bar" />
</Trigger>
于 2009-11-09T05:54:26.943 回答
0

检查这个:http ://en.csharp-online.net/WPF_Styles_and_Control_Templates%E2%80%94Event_Triggers 这可能会有所帮助

于 2009-11-08T07:58:10.823 回答