使ってみよう! Bing API/SDK

第7回 Hello, Bing Map App!──Silverlightで作るBing Mapsアプリケーション(7)

この記事を読むのに必要な時間:およそ 10.5 分

ListBoxの項目のスタイル

<Style x:Key="ListBoxItemStyle" TargetType="ListBoxItem">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="ListBoxItem">
                <Grid Background="{TemplateBinding Background}">
                    <VisualStateManager.VisualStateGroups>
                        <VisualStateGroup x:Name="CommonStates">
                            <VisualState x:Name="Normal"/>
                            <VisualState x:Name="MouseOver">
                                <Storyboard>
                                    <DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="selectedItem"/>
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="Disabled" />
                        </VisualStateGroup>
                        <VisualStateGroup x:Name="SelectionStates">
                            <VisualState x:Name="Unselected"/>
                            <VisualState x:Name="Selected" />
                        </VisualStateGroup>
                        <VisualStateGroup x:Name="FocusStates">
                            <VisualState x:Name="Focused" />
                            <VisualState x:Name="Unfocused"/>
                        </VisualStateGroup>
                    </VisualStateManager.VisualStateGroups>
                    <Border x:Name="selectedItem" Style="{StaticResource App.Border.Rollover}" Opacity="0">
                        <Rectangle Fill="{StaticResource App.Color.ItemRollover}" IsHitTestVisible="False" RadiusY="1" RadiusX="1"/>
                    </Border>
                    <ContentPresenter x:Name="contentPresenter" 
                                      ContentTemplate="{TemplateBinding ContentTemplate}" 
                                      Content="{TemplateBinding Content}" 
                                      HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}"/>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

ListBoxの項目内のリンクのスタイル:

<Style x:Key="HyperlinkButtonStyle" TargetType="HyperlinkButton" BasedOn="{StaticResource App.P1.Hyperlink}" >
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="HyperlinkButton">
                <Grid Background="{TemplateBinding Background}" Cursor="{TemplateBinding Cursor}">
                    <VisualStateManager.VisualStateGroups>
                        <VisualStateGroup x:Name="CommonStates">
                            <VisualState x:Name="Normal"/>
                            <VisualState x:Name="MouseOver">
                                <Storyboard>
                                    <ObjectAnimationUsingKeyFrames Duration="0" Storyboard.TargetProperty="Visibility" Storyboard.TargetName="UnderlineTextBlock">
                                        <DiscreteObjectKeyFrame KeyTime="0">
                                            <DiscreteObjectKeyFrame.Value>
                                                <Visibility>Visible</Visibility>
                                            </DiscreteObjectKeyFrame.Value>
                                        </DiscreteObjectKeyFrame>
                                    </ObjectAnimationUsingKeyFrames>
                                    <ObjectAnimationUsingKeyFrames Duration="0" Storyboard.TargetProperty="Visibility" Storyboard.TargetName="contentPresenter">
                                        <DiscreteObjectKeyFrame KeyTime="0">
                                            <DiscreteObjectKeyFrame.Value>
                                                <Visibility>Collapsed</Visibility>
                                            </DiscreteObjectKeyFrame.Value>
                                        </DiscreteObjectKeyFrame>
                                    </ObjectAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="Pressed">
                                <Storyboard>
                                    <ObjectAnimationUsingKeyFrames Duration="0" Storyboard.TargetProperty="Visibility" Storyboard.TargetName="UnderlineTextBlock">
                                        <DiscreteObjectKeyFrame KeyTime="0">
                                            <DiscreteObjectKeyFrame.Value>
                                                <Visibility>Visible</Visibility>
                                            </DiscreteObjectKeyFrame.Value>
                                        </DiscreteObjectKeyFrame>
                                    </ObjectAnimationUsingKeyFrames>
                                    <ObjectAnimationUsingKeyFrames Duration="0" Storyboard.TargetProperty="Visibility" Storyboard.TargetName="contentPresenter">
                                        <DiscreteObjectKeyFrame KeyTime="0">
                                            <DiscreteObjectKeyFrame.Value>
                                                <Visibility>Collapsed</Visibility>
                                            </DiscreteObjectKeyFrame.Value>
                                        </DiscreteObjectKeyFrame>
                                    </ObjectAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="Disabled" />
                        </VisualStateGroup>
                        <VisualStateGroup x:Name="FocusStates">
                            <VisualState x:Name="Focused" />
                            <VisualState x:Name="Unfocused" />
                        </VisualStateGroup>
                    </VisualStateManager.VisualStateGroups>
                    <TextBlock x:Name="UnderlineTextBlock" 
                               TextDecorations="Underline" 
                               Visibility="Collapsed" 
                               HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" 
                               Margin="{TemplateBinding Padding}" 
                               Text="{TemplateBinding Content}" 
                               VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
                   <ContentPresenter x:Name="contentPresenter" 
                                      ContentTemplate="{TemplateBinding ContentTemplate}" 
                                      Content="{TemplateBinding Content}" 
                                      HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" 
                                      Margin="{TemplateBinding Padding}" 
                                      VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

ListBoxの項目のコントロールの構成:

<DataTemplate x:Key="ListBoxItemTemplate">
    <ListBoxItem Style="{StaticResource ListBoxItemStyle}">
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto" />
                <ColumnDefinition />
            </Grid.ColumnDefinitions>
            <Border Width="60" BorderBrush="LightGray" BorderThickness="1" Background="White" Padding="2" RenderTransformOrigin="0.5,0.5" Margin="10">
                <Border.RenderTransform>
                    <CompositeTransform Rotation="-10"/>
                </Border.RenderTransform>
                <Border.Effect>
                    <DropShadowEffect BlurRadius="5" ShadowDepth="1" Color="Gray" Direction="250" />
                </Border.Effect>
                <Image Source="{Binding BitmapImage}" />
            </Border>
            <StackPanel Grid.Column="1" VerticalAlignment="Center">
                <HyperlinkButton Content="{Binding Name}" Style="{StaticResource HyperlinkButtonStyle}" 
                                 Click="HyperlinkButton_Click" />
            </StackPanel>
        </Grid>
    </ListBoxItem>
</DataTemplate>

デザイン部分は以上です。見た目を少しよくするためにコードが長くなっています。上記部分にもSDKで用意されいてるスタイルApp.Border.Rolloverなど)が使用されています。マウスポインターをListBoxの項目に重ねたとき見た目を切り替えるなどの処理が記述されています。

これらをすべてVisual Studioで記載したわけではなく,実際にはデザイナツールであるExpression Blend 4を使用して編集しています。ListBoxのデフォルトのスタイルをコピーして書き換えています。デフォルトのスタイルはMSDNライブラリにも記載されています。

ListBoxの項目の構成を記述しているListBoxItemTemplateでは,PhotoEntityのプロパティの内容を表示するため,データバンディング({Binding Name}と{Binding BitmapImage}部分)も記述しています。説明は省略しますが,データバインディングもXAMLの大きな特徴のひとつです。

項目を構成するコントロールの中のHyperlinkButtonについても,スタイルを定義しています(HyperlinkButtonStyle部分⁠⁠。SDKにはHyperlinkButton用にスタイルが用意されているのですが,見た目がBing Mapsと異なるため,そのスタイルを参照しつつ別に用意しました。

イベントの仮処理

上記のXAMLのコードには,次のイベント記述の部分が含まれています。

  • Click="HyperlinkButton_Click"
  • Drop="PhotoListBox_Drop"
  • Click="Button_Click"

コピーした場合はこれらに対応する処理がないため実行時にエラーになってしまいます。今回は何もしない空のメソッドをコードビハインドに記述しておきましょう。記述するといっても自分で書くのではなくVisual Studioの機能を利用してください。デザイナのメニュー図3またはプロパティウィンドウなどを使って自動でメソッドをコードに挿入するようにします。

図3 イベントハンドラーの追加

図3 イベントハンドラーの追加

正しく追加された場合は,以下のコードが,MyPhotoPanel.xaml.cs内に記述されています。

private void HyperlinkButton_Click(object sender, RoutedEventArgs e)
{
}

private void PhotoListBox_Drop(object sender, DragEventArgs e)
{
}

private void Button_Click(object sender, RoutedEventArgs e)
{
}

デザインの確認

実際の処理部分は次回に続きますが,現時点までの内容を確認できるように一時的なコードを書いてプラグインを実行してみましょう。たとえばパネル クラスのコードを次のように記述すると動作します。

MyPhotoPanel.xaml.cs

public MyPhotoPanel(MyPhotoPlugin plugin)
{
    InitializeComponent();

    this.plugin = plugin;
    this.PhotoItems = new ObservableCollection<PhotoEntity>();
    this.PhotoListBox.ItemsSource = this.PhotoItems;

    // 一時的なコード
    for (var i = 0; i < 10; ++i)
    {
        var item = new PhotoEntity()
        {
            Name = "写真" + i.ToString(),
            BitmapImage = new BitmapImage(new Uri("http://image.gihyo.co.jp/assets/images/ICON/2010/thumb/TH64_641_bing-sdk.png"))
        };
        this.PhotoItems.Add(item);
    }
}

実行結果は図4の通りです。Bing Mapsのようなデザインになったでしょうか?

図4 実行結果

図4 実行結果

今回はここまでです。次回はアプリの動作を記述していきます。お楽しみに。

著者プロフィール

松江祐輔(まつえゆうすけ)

日本システムウエア株式会社 勤務。現在,ハードウェア設計・検証業務を担当。大学生・大学院生時代はベンチャー企業 有限会社ミレニアムシステムズにプログラマーとして従事。趣味はプログラミング。好きな言語はVisual Basic。Microsoft MVP for Windows Live Platform(Jul 2010 - Jun 2011),Windows Live(Jul 2011 - Jun 2013)。

URL:http://katamari.jp