2011-07-15 4 views
3

垂直スタックパネルに一連のボタンを持つWPFアプリケーションがあります。これはDVRメニューのようになります。私は新しいメニューページが読み込まれるたびにボタン/コントロールがすべて{unfade、fall、deblur、anything}の存在になるアニメーションを作成する方法を考え出しました。私が本当に気に入っているのは、そのアニメーションの位置やタブストップのプロパティに基づいて、わずかに異なる時間に各ボタンでアニメーションを開始させることです。したがって、最初のボタンは最初のボタン、次に最初のボタン、最後のボタン、最後のボタンまで50msの遅延があります(ただし、最初のボタンは2番目のボタンの前に終了する必要はありません開始する)。もちろん、ボタンごとに異なるアニメーションを作成することもできますが、もう少し洗練されたソリューションを希望しています。ストーリーボードのBeginTimeにコントロールのプロパティをロードする方法はありません。 XAMLのみを使用する良い方法はありますか、これはコードビハインドを必要としますか?後者の場合、これをビヘイビアにパッケージ化し、後でその宣言的に宣言的にロードすることが可能かどうか、または命令コードを永遠に守っていますか?WPFアニメーションの設定方法BeginTimeコントロールのプロパティ(Top/Tabstop)に基づいて

答えて

8

短い答えは私の知る限りではありませんちょうどあなたはXAMLで何を求めているのですか?

WPFでアニメーションを行う方法はたくさんありますが、XAMLでアニメーションを作成する唯一の方法は、ストーリーボードを使用することです。要素間でストーリーボードを共有する唯一の方法は、Style、ControlTemplate、DataTemplateなどのリソースにパッケージ化することです。ただし、ストーリーボードをリソースとして使用するには、Freezableでなければなりません。つまり、アニメーションBeginTimeをアニメーションのターゲットのプロパティ(TabIndexなど)に関連付ける必要があるデータバインディング式を含むことはできませんあなたのボタンの他​​のプロパティ)。何らかの方法でアニメーションのBeginTimeをButtonのプロパティにバインドできたとしても、codebehindを使用してValueConverterを作成してButtonプロパティ値をTimeSpan値(希望する50msの累積遅延)に変換する必要があります。

ので正確あなたが望むを行うために、あなたはこの例に示すように、分離コードを使用する必要があります:

XAML:

<StackPanel HorizontalAlignment="Left" Width="100" Loaded="StackPanel_Loaded"> 
    <Button Content="Button1"/> 
    <Button Content="Button2"/> 
    <Button Content="Button3"/> 
    <Button Content="Button4"/> 
    <Button Content="Button5"/> 
    <Button Content="Button6"/> 
    <Button Content="Button7"/> 
    <Button Content="Button8"/> 
    <Button Content="Button9"/> 
    <Button Content="Button10"/> 
</StackPanel> 

は、分離コード:

private void StackPanel_Loaded(object sender, RoutedEventArgs e) 
{ 
    StackPanel stackPanel = sender as StackPanel; 
    DoubleAnimation fadeInAnimation = new DoubleAnimation(1.0, new Duration(TimeSpan.FromMilliseconds(200))); 
    for (int i = 0; i < stackPanel.Children.Count; i++) 
    { 
     fadeInAnimation.BeginTime = TimeSpan.FromMilliseconds(i * 50); 
     stackPanel.Children[i].Opacity = 0.0; 
     stackPanel.Children[i].BeginAnimation(UIElement.OpacityProperty, (AnimationTimeline)fadeInAnimation.GetAsFrozen()); 
    } 
} 

つまり、XAMLを使用して目的の動作を近似する方法があります。たとえば、LinearGradientBrush OpacityMaskでのStackPanelを重ねる可能性があり、このような単一のストーリーボードであることをアニメーション:

XAML:。

<StackPanel HorizontalAlignment="Left" Width="100"> 
    <StackPanel.OpacityMask> 
     <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0"> 
      <GradientStop Color="Black"/> 
      <GradientStop x:Name="TransparentGradient" Color="Transparent"/> 
     </LinearGradientBrush> 
    </StackPanel.OpacityMask> 
    <StackPanel.Triggers> 
     <EventTrigger RoutedEvent="Loaded"> 
      <BeginStoryboard> 
       <Storyboard> 
        <DoubleAnimation 
         Storyboard.TargetName="TransparentGradient" Storyboard.TargetProperty="Offset" 
         To="1.0" Duration="0:0:0.5"/> 
        <ColorAnimation 
         Storyboard.TargetName="TransparentGradient" Storyboard.TargetProperty="Color" 
         To="Black" BeginTime="0:0:0.5" Duration="0:0:0.5"/> 
       </Storyboard> 
      </BeginStoryboard> 
     </EventTrigger> 
    </StackPanel.Triggers> 
    <Button Content="Button1"/> 
    <Button Content="Button2"/> 
    <Button Content="Button3"/> 
    <Button Content="Button4"/> 
    <Button Content="Button5"/> 
    <Button Content="Button6"/> 
    <Button Content="Button7"/> 
    <Button Content="Button8"/> 
    <Button Content="Button9"/> 
    <Button Content="Button10"/> 
</StackPanel> 

の一番下のフェードにあなたに素敵なトップを与えるだろう他の効果可能性小さな創造性でも可能ですが、アドバイスをお願いします。数行のコードで目的の効果を達成できるときに、複雑なXAMLソリューションを見つけるのにあまりにも多くの時間を費やさないようにしてください。

ハッピーコーディング!

+0

詳細な回答ありがとうございます。もし私ができるなら、私はあなたに+2を与えるだろう。 WPFの初心者であるため、XAMLに関連する*すべて* GUI関連のものか、多くのものがまだコードを必要とするかどうかはわかりませんでした。私はあなたが非常に確実にそれに答えたと思います。 (ええ、私は他の場所でのフェード/ワイプの例を見てきましたが、それは達成したい効果ではありませんが、とにかく感謝しています)。 –

関連する問題