2009-11-07 78 views
1

我重写了tabitem模板并创建了我自己的自定义样式。不过,我不确定如何为鼠标悬停事件编写事件触发器。如何使用WPF触发器将鼠标悬停在事件上对于选项卡项目?


对不起,迟到的回应,我没有得到意见通知(也许这应该改变?)。好吧,我会试着进一步解释这一点。我不添加评论,因为我需要发布示例代码。假设你有一个控件,任何控件。 比方说,你还定义了一些画笔作为资源。 所以:

<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从当前画笔做3秒钟动画MouseOverGradientBrush和从MouseOver事件的当前前景到MouseOverForeground? 我在例子中看到你通过逐渐改变渐变的偏移量来做到这一点。我现在要这样做。它增加了代码的大小,最终会变得非常混乱。除了刷子可能有不同数量的偏移量,或者一个可以是线性的,另一个可以是径向的。 我希望这更清楚。

回答

1

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

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

感谢您的所有回复。我的触发器工作正常。我只是不能为他们制作动画。我有一个更简单的wat使用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的背景(无论是)i值在鼠标悬停= TRUE触发( MouseOverGradientBrush)。上面的代码和动画有什么问题不起作用?我已经使用表情融合,我可以...

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

嘿Foovanadil是的工作。谢谢。 现在,有没有办法使用故事板在MouseOver事件上更改为MouseOverGradientBrush(不是单独指定每个偏移量,而是仅指定整个画笔资源)? – immuner 2009-11-12 20:09:27

+0

不确定你的意思。你想要改变实际的画笔资源到鼠标上的另一个画笔上面的触发器?你能否进一步解释你的具体情况?我的直觉反应是在设计时指定不同的画笔资源,然后交换您在触发器中使用的画笔资源(与使用一个画笔资源并尝试更改其内容)。这种方法在你的情况下不可行吗? – 2009-11-16 21:36:09

相关问题