我想在WPF中以编程方式创建按钮,在IsMouseOver == true
时增长到特定大小,并在IsMouseOver == false
时缩小到原始大小。
为了实现这种行为,我派生了Button
类,并添加了DependencyProperty
:
public class ScalableButton : Button
{
public Storyboard MouseOutAnimation
{
get { return (Storyboard)GetValue(MouseOutAnimationProperty); }
set { SetValue(MouseOutAnimationProperty, value); }
}
// Using a DependencyProperty as the backing store for MouseOutAnimation. This enables animation, styling, binding, etc...
public static readonly DependencyProperty MouseOutAnimationProperty =
DependencyProperty.Register("MouseOutAnimation", typeof(Storyboard), typeof(ScalableButton), new UIPropertyMetadata(null));
public ScalableButton(double originalScale, Style style)
: base()
{
CreateMouseOutAnimation(originalScale);
RenderTransform = new ScaleTransform(originalScale, 1, 0.5, 0.5);
RenderTransformOrigin = new Point(0.5, 0.5);
Style = style;
ApplyTemplate();
}
private void CreateMouseOutAnimation(double originalScale)
{
DoubleAnimation animX = new DoubleAnimation();
animX.To = originalScale;
animX.Duration = TimeSpan.FromMilliseconds(200);
DoubleAnimation animY = new DoubleAnimation();
animY.To = 1;
animY.Duration = TimeSpan.FromMilliseconds(200);
Storyboard sb = new Storyboard();
sb.Children.Add(animX);
sb.Children.Add(animY);
Storyboard.SetTarget(sb, this.RenderTransform);
Storyboard.SetTargetProperty(animX, new PropertyPath(ScaleTransform.ScaleXProperty));
Storyboard.SetTargetProperty(animY, new PropertyPath(ScaleTransform.ScaleYProperty));
MouseOutAnimation = sb;
}
}
然后,我创建了一个带有Style
的{{1}}来为我的按钮创建自定义外观,并添加了ControlTemplate
资源来扩展它们,另一个用于缩小它们是问题:
Storyboard
那么,我如何指定<Style TargetType="{x:Type rgw:ScalableButton}" x:Key="EllipseWithText" >
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type rgw:ScalableButton}">
<ControlTemplate.Resources>
<Storyboard x:Key="MouseOverAnimation">
<DoubleAnimation Storyboard.TargetName="ButtonGrid" Storyboard.TargetProperty="RenderTransform.ScaleX" To="1.2" Duration="0:0:1" />
<DoubleAnimation Storyboard.TargetName="ButtonGrid" Storyboard.TargetProperty="RenderTransform.ScaleY" To="1.2" Duration="0:0:1" />
</Storyboard>
<Storyboard x:Key="MouseOutAnimation">
<!-- This would be the one which scales down -->
</Storyboard>
</ControlTemplate.Resources>
<Grid x:Name="ButtonGrid" RenderTransform="{TemplateBinding RenderTransform}" RenderTransformOrigin="0.5, 0.5">
<Ellipse x:Name="ButtonEllipse" Height="50" Width="150" Fill="#00000000" StrokeThickness="1" Stroke="Black" />
<TextBlock x:Name="ButtonText" Width="150" TextAlignment="Center" HorizontalAlignment="Center" VerticalAlignment="Center" TextWrapping="Wrap"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Trigger.EnterActions>
<BeginStoryboard Storyboard="{StaticResource MouseOverAnimation}" />
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard Storyboard="{StaticResource MouseOutAnimation}" />
</Trigger.ExitActions>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
作为资源?
或者是否有其他方法可以实现可伸缩按钮?
答案 0 :(得分:1)
不需要派生按钮。
不要在ExitActions动画中设置To
属性。这将自动从当前属性值动画回原始属性值。请注意,在下面的示例中,我首先设置ScaleX = 0.5
。
<Style TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid RenderTransformOrigin="0.5, 0.5">
<Grid.RenderTransform>
<ScaleTransform x:Name="scale" ScaleX="0.5"/>
</Grid.RenderTransform>
<Ellipse Height="50" Width="150" Fill="Transparent" StrokeThickness="1" Stroke="Black" />
<TextBlock Width="150" HorizontalAlignment="Center" VerticalAlignment="Center"
TextAlignment="Center" TextWrapping="Wrap" Text="{TemplateBinding Content}"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="scale"
Storyboard.TargetProperty="ScaleX"
To="1.2" Duration="0:0:0.3"/>
<DoubleAnimation Storyboard.TargetName="scale"
Storyboard.TargetProperty="ScaleY"
To="1.2" Duration="0:0:0.3"/>
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="scale"
Storyboard.TargetProperty="ScaleX"
Duration="0:0:0.2"/>
<DoubleAnimation
Storyboard.TargetName="scale"
Storyboard.TargetProperty="ScaleY"
Duration="0:0:0.2"/>
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
编辑:
虽然MinWidth
肯定不是比例因素:您可以像下面那样绑定。
<ScaleTransform ScaleX="{Binding MinWidth,
RelativeSource={RelativeSource Mode=TemplatedParent}}"/>