Silverlightでフェードインとフェードアウト

おことわり

Visual Web Developer 2010 Express Editionのみの環境です。Expression Blend使うともっとクールな方法があるやも。
後、Silverlightはまだ素人なんで、あんまりいいコードじゃない可能性はあります。俺的Hello Worldみたいなもんという事でお許しを。

やりたいこと

複数ページで構成される業務系とかのSilverlightアプリケーションで、ページ遷移をフェードイン/フェードアウトで表示させたい。

プロジェクトの作成

ファイル→新しいプロジェクト→Silverlightアプリケーションで適当にプロジェクトを作る。
ここで出来るひな形にはApp.xamlとMainPage.xamlがあり、AppのRootVisualにMainPageが指定されている状態を想定。
なお、言語はとりあえずC#で。VB派の人許して。

アニメーション作る

アニメーションはMainPageのResourceとして埋め込む。
こんなん。

<UserControl x:Class="FadeInOut.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400" Name="rootContainer">

    <UserControl.Resources>
        <Storyboard x:Name="fadeIn">
            <DoubleAnimationUsingKeyFrames BeginTime="00:00:00"  
                            Storyboard.TargetName="rootContainer" 
                            Storyboard.TargetProperty="(UIElement.Opacity)">
                <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0"/>
                <SplineDoubleKeyFrame KeyTime="00:00:01" Value="1"/>
            </DoubleAnimationUsingKeyFrames>
        </Storyboard>
        <Storyboard x:Name="fadeOut">
            <DoubleAnimationUsingKeyFrames BeginTime="00:00:00"  
                            Storyboard.TargetName="rootContainer" 
                            Storyboard.TargetProperty="(UIElement.Opacity)">
                <SplineDoubleKeyFrame KeyTime="00:00:00" Value="1"/>
                <SplineDoubleKeyFrame KeyTime="00:00:01" Value="0"/>
            </DoubleAnimationUsingKeyFrames>
        </Storyboard>
    </UserControl.Resources>
</UserControl>

注意点としては、デフォルトではついていないMainPageにrootContainerという名前をつけているところ。
後はどうせ使わないんでGridを消してるとこくらいかな。
そこだけ気をつければ、UserControl.Resources内を貼りつけてもらえればどんなコントロールにも貼りつけられると思われ。

ページ作る

右のソリューションエクスプローラのプロジェクトのところ右クリック→追加→新しい項目→Silverlightユーザーコントロールで、ページ作る。
テスト用に2ページは必要なんで、Page1とPage2という名前で作ったことにして進める。
テスト用に、ページ遷移のためのボタンでも貼りつけておくこと。それ以外は自由に貼って問題なし。

MainPage.xaml.csにコード書く

こんなん。

public partial class MainPage : UserControl {
    private Control page;
    public MainPage() {
        InitializeComponent();
        this.fadeIn.Completed += new EventHandler(fadeIn_Completed);
        this.fadeOut.Completed += new EventHandler(fadeOut_Completed);
        this.MovePage(new Page1());
    }
    public void MovePage(Control page) {
        this.page = page;
        this.fadeOut.Begin();
    }

    void fadeOut_Completed(object sender, EventArgs e) {
        this.Content = this.page;
        this.fadeIn.Begin();
    }
    void fadeIn_Completed(object sender, EventArgs e) {
    }
}

MovePageが切り替え処理で、中身はさっき定義したアニメーションのフェードアウト呼び出して、それが完了したらコンテンツ読み込んで、フェードインするってだけ。
後、初期ページにPage1を指定してる。

テスト用コード

最後にさっき作ったPage1とPage2に、それぞれこんな感じのコードを書く。

private void button1_Click(object sender, RoutedEventArgs e)
{
    (App.Current.RootVisual as MainPage).MovePage(new Page2());
}

MainPageのMovePageメソッド呼び出して、引数にPage1だったPage2のインスタンスを、Page2だったらPage1のインスタンスを指定する。だけ。

完成

こんな感じ。


これだけだとダサイけど、アニメーション変えたり色々遊べば、ということで。
Silverlightまだ全体的に記事が少ないんで、こういう簡単な事で結構はまって投げだす人が多いんじゃないかなと思って一応公開。