如何将DependencyProperty指定为资源

时间:2012-05-10 15:32:17

标签: c# wpf

我想在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> 作为资源?

或者是否有其他方法可以实现可伸缩按钮?

1 个答案:

答案 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}}"/>