2012-05-10 25 views
0

我想在WPF中以编程方式创建按钮,当IsMouseOver == true增长到特定大小时,在IsMouseOver == false时缩小到原始大小。如何指定一个DependencyProperty作为资源

为了实现这一行为,我得到的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; 
    } 
} 

然后,我创建了一个StyleControlTemplate,使我的按键的自定义外观,并添加了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> 

所以,我怎么可以指定ScalableButton.MouseOutAnimation作为一种资源?

或者是否有其他方式实现可缩放按钮?

+0

我不明白你的问题......这段代码有什么问题? –

+0

'originalScale'与1.0有什么不同吗?你的'MouseOverAnimation'如何考虑? – Clemens

+0

为什么从'Button'完全得到?为什么不直接在自定义模板中做所有这些? –

回答

1

不需要导出的Button。

不要在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}}"/> 
+0

是的,谢谢你,它几乎完美!当最初设置ScaleX时,它完美地工作,但是,当我试图绑定某些东西时,它不适用,它保持在1.0。也许我做错了什么。我使用'MinWidth'属性来设置最初的'ScaleX'('ScaleX =“{TemplateBinding MinWidth}”)。有任何想法吗? – Bhaclash

+0

查看编辑答案。 – Clemens

+0

你当然也可以遵循你原来的方法,并通过TemplateBinding将Grid的RenderTransform绑定到按钮的RenderTransform。但是你必须确保RenderTransform总是包含一个ScaleTransform。 – Clemens

相关问题