2012-05-10 18 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

相關問題