4

此问题之前已经被问到过,但在大多数情况下不超过2年前,并且通常只针对WPF。答案可能仍然存在,但在这里。我正在尝试构建一个三角形(箭头)按钮,当鼠标悬停在它上面时,它会改变颜色并在尺寸上变大。我已经为一个按钮工作。但现在我需要箭头指向不同方向的按钮。我想尽可能多地重用代码。没有使用自定义按钮控件,我想不出一种完全使用相同样式的方式,所以我试图通过将鼠标重新用于资源来重复使用鼠标。当我在我的按钮模板的VisualStateManager中将Storyboard作为StaticResource引用时,它使我的按钮完全消失。为什么这不起作用?如何在VisualStateManager中重用故事板在Silverlight 5中

<UserControl 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:System="clr-namespace:System;assembly=mscorlib" mc:Ignorable="d" 
x:Class="SilverlightTest.MainPage" 
Width="640" Height="480"> 
<UserControl.Resources> 
    <Storyboard x:Key="ArrowMouseOver"> 
     <DoubleAnimation Duration="0:0:0.165" To="1.25" Storyboard.TargetProperty="(UiElement.RenderTransform).(ScaleTransform.ScaleX)" Storyboard.TargetName="polygon"/> 
     <DoubleAnimation Duration="0:0:0.165" To="1.25" Storyboard.TargetProperty="(UiElement.RenderTransform).(ScaleTransform.ScaleY)" Storyboard.TargetName="polygon"/> 
     <ColorAnimation Duration="0:0:0.165" To="#FF9BD6FF" Storyboard.TargetProperty="(Shape.Fill).(GradientBrush.GradientStops)[1].(GradientStop.Color)" Storyboard.TargetName="polygon" d:IsOptimized="True"/> 
     <ColorAnimation Duration="0:0:0.165" To="#FF70ACDF" Storyboard.TargetProperty="(Shape.Fill).(GradientBrush.GradientStops)[0].(GradientStop.Color)" Storyboard.TargetName="polygon" d:IsOptimized="True"/> 
     <ColorAnimation Duration="0:0:0.165" To="#FF7DAEFF" Storyboard.TargetProperty="(Shape.Stroke).(GradientBrush.GradientStops)[1].(GradientStop.Color)" Storyboard.TargetName="polygon" d:IsOptimized="True"/> 
     <ColorAnimation Duration="0:0:0.165" To="#FF2B5CB4" Storyboard.TargetProperty="(Shape.Stroke).(GradientBrush.GradientStops)[0].(GradientStop.Color)" Storyboard.TargetName="polygon" d:IsOptimized="True"/> 
    </Storyboard> 

    <Style x:Key="LeftArrow" TargetType="Button"> 
     <Setter Property="Cursor" Value="Hand"/> 
     <Setter Property="Template"> 
      <Setter.Value> 
       <ControlTemplate TargetType="Button"> 
        <Grid x:Name="grdRoot" RenderTransformOrigin="0.5,0.5"> 
         <Grid.RowDefinitions> 
          <RowDefinition Height="Auto"/> 
          <RowDefinition Height="Auto"/> 
         </Grid.RowDefinitions> 
         <VisualStateManager.VisualStateGroups> 
          <VisualStateGroup x:Name="CommonStates"> 
           <VisualStateGroup.Transitions> 
            <VisualTransition From="MouseOver" GeneratedDuration="0:0:0.165"/> 
           </VisualStateGroup.Transitions> 
           <VisualState x:Name="Normal"/> 
           <VisualState x:Name="MouseOver" Storyboard="{StaticResource ArrowMouseOver}"> 
           </VisualState> 
           <VisualState x:Name="Pressed"/> 
           <VisualState x:Name="Disabled"/> 
          </VisualStateGroup> 
         </VisualStateManager.VisualStateGroups> 
         <Polygon x:Name="polygon" Grid.Row="0" Margin="1" StrokeThickness="{TemplateBinding BorderThickness}" HorizontalAlignment="Center" RenderTransformOrigin="0.5,0.5"> 
          <Polygon.Points> 
           <Point X="10"/> 
           <Point X="0" Y="5" /> 
           <Point Y="10" X="10" /> 
          </Polygon.Points> 
          <Polygon.RenderTransform> 
           <ScaleTransform /> 
          </Polygon.RenderTransform> 
          <Polygon.Fill> 
           <LinearGradientBrush EndPoint="0.5,0" StartPoint="0.5,1"> 
            <GradientStop Color="#FFA9A9A9"/> 
            <GradientStop Color="#FFD3D3D3" Offset="1"/> 
           </LinearGradientBrush> 
          </Polygon.Fill> 
          <Polygon.Stroke> 
           <LinearGradientBrush EndPoint="0.5,0" StartPoint="0.5,1"> 
            <GradientStop Color="#FF696969"/> 
            <GradientStop Color="#FF939393" Offset="1"/> 
           </LinearGradientBrush> 
          </Polygon.Stroke> 
         </Polygon> 
         <ContentPresenter Grid.Row="1" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/> 
        </Grid> 
       </ControlTemplate> 
      </Setter.Value> 
     </Setter> 
    </Style> 

</UserControl.Resources> 
<Grid x:Name="LayoutRoot" Background="White"> 
    <Button Style="{StaticResource LeftArrow}" HorizontalAlignment="Left" VerticalAlignment="Top"> 
    </Button> 
</Grid> 

回答

1

这听起来像你应该介绍自己的Button类。 我会做它像这样:

<my:GlowingArrowButton ArrowDirection="Left"/> 

而且你generic.xaml:

<Style TargetType="my:GlowingArrowButton"> 
    <Setter Property="Cursor" Value="Hand"/> 
    <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="my:GlowingArrowButton"> 
       <Grid x:Name="grdRoot" RenderTransformOrigin="0.5,0.5"> 
        <Grid.RowDefinitions> 
         <RowDefinition Height="Auto"/> 
         <RowDefinition Height="Auto"/> 
        </Grid.RowDefinitions> 
        <VisualStateManager.VisualStateGroups> 
         <VisualStateGroup x:Name="CommonStates"> 
          <VisualStateGroup.Transitions> 
           <VisualTransition From="MouseOver" GeneratedDuration="0:0:0.165"/> 
          </VisualStateGroup.Transitions> 
          <VisualState x:Name="Normal"/> 
          <VisualState x:Name="MouseOver" 
<Storyboard> 
    <DoubleAnimation Duration="0:0:0.165" To="1.25" Storyboard.TargetProperty="(UiElement.RenderTransform).(ScaleTransform.ScaleX)" Storyboard.TargetName="polygon"/> 
    <DoubleAnimation Duration="0:0:0.165" To="1.25" Storyboard.TargetProperty="(UiElement.RenderTransform).(ScaleTransform.ScaleY)" Storyboard.TargetName="polygon"/> 
    <ColorAnimation Duration="0:0:0.165" To="#FF9BD6FF" Storyboard.TargetProperty="(Shape.Fill).(GradientBrush.GradientStops)[1].(GradientStop.Color)" Storyboard.TargetName="polygon" d:IsOptimized="True"/> 
    <ColorAnimation Duration="0:0:0.165" To="#FF70ACDF" Storyboard.TargetProperty="(Shape.Fill).(GradientBrush.GradientStops)[0].(GradientStop.Color)" Storyboard.TargetName="polygon" d:IsOptimized="True"/> 
    <ColorAnimation Duration="0:0:0.165" To="#FF7DAEFF" Storyboard.TargetProperty="(Shape.Stroke).(GradientBrush.GradientStops)[1].(GradientStop.Color)" Storyboard.TargetName="polygon" d:IsOptimized="True"/> 
    <ColorAnimation Duration="0:0:0.165" To="#FF2B5CB4" Storyboard.TargetProperty="(Shape.Stroke).(GradientBrush.GradientStops)[0].(GradientStop.Color)" Storyboard.TargetName="polygon" d:IsOptimized="True"/> 
</Storyboard> 
          </VisualState> 
          <VisualState x:Name="Pressed"/> 
          <VisualState x:Name="Disabled"/> 
         </VisualStateGroup> 
        </VisualStateManager.VisualStateGroups> 


        <LayoutTransformer 
         LayoutTransform="{Binding Path=ArrowDirection, 
          RelativeSource={RelativeSource TemplatedParent}, 
          Converter={StaticResource RotationTranslator_ToBeImplemented}}" 
         Grid.Row="0" 
         HorizontalAlignment="Center"> 
        <Polygon 
         x:Name="polygon" 

         Margin="1" 
         StrokeThickness="{TemplateBinding BorderThickness}" 

         RenderTransformOrigin="0.5,0.5"> 
         <Polygon.Points> 
          <Point X="10"/> 
          <Point X="0" Y="5" /> 
          <Point Y="10" X="10" /> 
         </Polygon.Points> 
         <Polygon.RenderTransform> 
          <ScaleTransform /> 
         </Polygon.RenderTransform> 
         <Polygon.Fill> 
          <LinearGradientBrush EndPoint="0.5,0" StartPoint="0.5,1"> 
           <GradientStop Color="#FFA9A9A9"/> 
           <GradientStop Color="#FFD3D3D3" Offset="1"/> 
          </LinearGradientBrush> 
         </Polygon.Fill> 
         <Polygon.Stroke> 
          <LinearGradientBrush EndPoint="0.5,0" StartPoint="0.5,1"> 
           <GradientStop Color="#FF696969"/> 
           <GradientStop Color="#FF939393" Offset="1"/> 
          </LinearGradientBrush> 
         </Polygon.Stroke> 
        </Polygon> 
       </LayoutTransformer> 


        <ContentPresenter 
         Grid.Row="1" 
         HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" 
         VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/> 
       </Grid> 
      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 

和代码:

public class GlowingArrowButton : ButtonBase 
{ 
    public GlowingArrowButton() 
    { 
     DefaultStyleKey = typeof (GlowingArrowButton); 
    } 

    public ArrowDirection ArrowDirection 
    { 
     get { return (ArrowDirection) GetValue(ArrowDirectionProperty); } 
     set { SetValue(ArrowDirectionProperty, value); } 
    } 

    public static readonly DependencyProperty ArrowDirectionProperty = 
     DependencyProperty.Register("ArrowDirection", typeof(ArrowDirection), typeof(GlowingArrowButton), new PropertyMetadata(default(ArrowDirection))); 
} 

public enum ArrowDirection 
{ 
    Left, 
    Up, 
    Right, 
    Down 
} 

[编辑] 书面但未经检验:

public class RotationTranslator : IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     var arrowDirection = (ArrowDirection) value; 
     switch (arrowDirection) 
     { 
       case ArrowDirection.Left: return new RotateTransform{ Angle = 0 }; 

       case ArrowDirection.Up: return new RotateTransform { Angle = 90 }; 

       case ArrowDirection.Right: return new RotateTransform { Angle = 180 }; 

       case ArrowDirection.Down: return new RotateTransform { Angle = -90 }; 
     } 
     throw new InvalidOperationException(); 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture){throw new NotSupportedException();} 
}