Expression Blend 3: Behaviorを使ったコーディングレスでのSilverlight 3アプリのインタラクションデザイン

Silverlight 3 Betaと同時にExpression Blend 3 Previewが公開されていますが、便利な新機能が搭載されています。

ここでは、Behaviorについて紹介したいと思います。

Blend 1/Blend 2を使ってSilverlight のアプリケーションを開発されたことがある人は、いつも次のような疑問を感じていたと思います。

「何かをクリックしたタイミングでタイムラインのアニメーションを簡単に呼び出す方法はないのだろうか」

「よく使うオブジェクトの操作をコードを書かないで実行できないのだろうか」

Blend 3からは、これらの疑問を解決する「Behavior」機能が搭載されています。

  • CallMethodAction : 指定したオブジェクトのメソッドを呼び出す
  • ChangePropertyAction: 指定したオブジェクトのプロパティを変更する
  • ControlStoryboardAction: 指定したStoryboardの動きを制御する
  • InvokeCommandAction: コマンドにパラメータを渡して実行する (現時点で詳細不明)
  • SmoothMoveBehavior: 水平・垂直方向のイージング(easing)を指定してアニメーションを実行する

この記事では、いくつかを使って、Silverlight 3でのメディア再生をコーディングを行わないで実現してみたいと思います。

Blend3-MediaDemo-001

GridをMediaElement側とButton側で分けて、上側にMediaElement (myME)、下側にButtonを3つ (playButton, pauseButton, stopButton)を配置します。

※ ここでは省略しますが、MediaElementに対しては何らかのSourceプロパティを割り当て、AutoPlayプロパティをFalseに指定してください。[Add Existing Item]でプロジェクトにメディアファイル追加する場合、現時点のビルドだと自動的にWeb Site側のプロジェクトにコピーされずテスト時エラーとなることが分かっています。

今までの開発ですと、それぞれのボタンのイベントハンドラをC#やVisual Basicで記述する必要がありました。Blend 3は違います。

貼り付けた3つのボタンにBehaviorを使い、MediaElementのメソッドを呼び出すためのトリガーを記述します。

[Asset Library]を開き、[Behaviors]をクリックすると、次のような画面になります。

Blend3-Behaviors

この画面から[CallMethodAction]をドラッグして、[Objects and Timeline]で一覧になっているplayButton、pauseButton、stopButtonへドロップします。
例: pauseButtonにドロップしている途中の画像

Blend3-DragDrop-Behavior

 

 

それぞれのButtonに対するCallMethodActionを指定します。

[playButton]に対して、[Miscellaneous]を展開し、
TargetName: myME
MethodName: Play

と指定します。

Blend3-CallMethodAction-Play

[pauseButton]に対して、[Miscellaneous]を展開し、
TargetName: myME
MethodName: Pause

と指定します。

Blend3-CallMethodAction-Pause

[stopButton]に対して、[Miscellaneous]を展開し、
TargetName: myME
MethodName: Stop

と指定します。

Blend3-CallMethodAction-Stop

[F5]を押してテスト実行します。

※ メディアファイルを追加した場合は、エラーとなるので、いったんBlend 3に戻り、プロジェクトのメディアファイルをWeb siteプロジェクトのClientBinにコピーして、再度[F5]で実行してください。

実行結果:

SL3-mediaplayback

続いて、Storyboardを定義して動かしてみましょう。Blend 3に戻り、[Objects and Timeline]の下にある[+]ボタンをクリックして、Storyboardを作ります。名前は「MyStory」としてください。

ここでは、Perspective 3Dを利用して、12秒かけて、myMEというMediaElementをx軸、y軸、z軸、それぞれ360度回転させてみます。

緑色の+をクリックして、0秒時点で、myMEに対してキーフレームを割り当てます。

Blend3-Timeline-01

タイムライン上、12秒後の位置に移動し、TransformのProjectionのX, Y, Zをそれぞれ360と設定します。

Blend3-Timeline-02

タイムラインを再生してみると、回転していることがわかります。

Blend3-Timeline-03

 

 

赤色の丸をクリックして、タイムラインの記録をオフにします。

[Asset Library]から[Behaviors]を選択肢、[ControlStoryboardAction] をplayButtonにドラッグ&ドロップします。

Blend3-ControlStoryboardAction

[F5]を押してテスト実行します。

実行結果の例:

SL3-mediaplayback-3d

 

というわけで、Blend 3を利用すると、今までコーディングが必要だった処理がBehaviorを使って、コーディングレスで実現できます。

参考までに、XAMLの中身は次のような感じになります。

<UserControl     
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"    
    xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"    
    xmlns:i="clr-namespace:Microsoft.Expression.Interactivity;assembly=Microsoft.Expression.Interactivity"    
    xmlns:im="clr-namespace:Microsoft.Expression.Interactivity.Media;assembly=Microsoft.Expression.Interactivity"    
    x:Class="MediaDemo_0323.MainControl"    
    Width="640" Height="480">     
    
    <UserControl.Resources>    
        <Storyboard x:Name="MyStory">     
            <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="myME" Storyboard.TargetProperty="(UIElement.Projection).(PlaneProjection.RotationX)">     
                <EasingDoubleKeyFrame KeyTime="00:00:00" Value="0"/>     
                <EasingDoubleKeyFrame KeyTime="00:00:11.2000000" Value="360"/>     
            </DoubleAnimationUsingKeyFrames>    
            <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="myME" Storyboard.TargetProperty="(UIElement.Projection).(PlaneProjection.RotationY)">     
                <EasingDoubleKeyFrame KeyTime="00:00:00" Value="0"/>     
                <EasingDoubleKeyFrame KeyTime="00:00:11.2000000" Value="360"/>     
            </DoubleAnimationUsingKeyFrames>    
            <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="myME" Storyboard.TargetProperty="(UIElement.Projection).(PlaneProjection.RotationZ)">     
                <EasingDoubleKeyFrame KeyTime="00:00:00" Value="0"/>     
                <EasingDoubleKeyFrame KeyTime="00:00:11.2000000" Value="360"/>     
            </DoubleAnimationUsingKeyFrames>    
        </Storyboard>    
    </UserControl.Resources>    
    
    <Grid x:Name="LayoutRoot" Background="White">     
        <Grid.RowDefinitions>    
            <RowDefinition Height="0.79*"/>     
            <RowDefinition Height="0.21*"/>     
        </Grid.RowDefinitions>    
        <MediaElement x:Name="myME" Margin="1,1,0,0" AutoPlay="False" Source="https://myserver:8080/dlife.wmv">     
            <MediaElement.Projection>    
                <PlaneProjection/>    
            </MediaElement.Projection>    
        </MediaElement>    
        <Button x:Name="playButton" FontSize="24" HorizontalAlignment="Left" Margin="8,8,0,8" Width="204" Grid.Row="1" Content="再生">     
            <i:Interaction.Triggers>    
                <i:EventTrigger EventName="Click">     
                    <i:CallMethodAction TargetName="myME" MethodName="Play"/>     
                    <im:ControlStoryboardAction Storyboard="{StaticResource MyStory}" ControlStoryboardOption="Play"/>     
                </i:EventTrigger>    
            </i:Interaction.Triggers>    
        </Button>    
        <Button x:Name="pauseButton" Margin="216,8,220,8" Grid.Row="1" Content="一時停止" FontSize="24">     
            <i:Interaction.Triggers>    
                <i:EventTrigger EventName="Click">     
                    <i:CallMethodAction TargetName="myME" MethodName="Pause"/>     
                    <im:ControlStoryboardAction ControlStoryboardOption="Pause" Storyboard="{StaticResource MyStory}"/>     
                </i:EventTrigger>    
            </i:Interaction.Triggers>    
        </Button>    
        <Button x:Name="stopButton" HorizontalAlignment="Right" Margin="0,8,12,8" Width="204" Grid.Row="1" Content="停止" FontSize="24">     
            <i:Interaction.Triggers>    
                <i:EventTrigger EventName="Click">     
                    <i:CallMethodAction TargetName="myME" MethodName="Stop"/>     
                    <im:ControlStoryboardAction Storyboard="{StaticResource MyStory}" ControlStoryboardOption="Stop"/>     
                </i:EventTrigger>    
            </i:Interaction.Triggers>    
        </Button>    
    </Grid>    
</UserControl>    
 

今後もBlend 3を使ったSilverlight 3アプリケーションのデザインと開発について、紹介していきたいと考えています。