Partager via


実例で学ぶアプリケーション開発 ver.2 - サンプルアプリケーションのポイント (5) - Client(Silverlight)アプリケーション(UI)側

昨日に引き続いて、本日は、クライアントアプリケーション(UI)側の簡単なアーキテクチャ解説をします。

Navigation Framework の利用

本ソリューションサンプルでは、Silverlight アプリケーションプロジェクトのテンプレートとして 「Silverlight Business Application」を利用しています。これは、Navigation Frameworkを搭載しています。Tech・EdのT6-401等では、このテンプレートや、「Navigationアプリケーション」を選択していませんでしたが、実際のプロトタイピングでは、このフレームワークを使った方が便利な場合も多いですので、こちらもぜひ使ってみてください。(ちなみに、Tech・Ed 2009では、Silverlight 3 + 「Business Application」テンプレートで開発デモを行いました)

これにより、URL による Silverlight ページへのアクセスが可能となっています。

① URL マッピングの利用

Navigation Framework のURLマッピング機能を利用することにより、各ページへのアクセスのURLを容易にカスタマイズすることが可能となっています。

URL マッピングのサンプルは以下の通りです。

7行目の

<uriMapper:UriMapping Uri="/{pageName}" MappedUri="/Views/{pageName}.xaml"/>

という箇所に注目してください。

サンプル:\MSStoreSample\ MSStoreSample \MainPage.xaml

 <navigation:Frame x:Name="ContentFrame" Style="{StaticResource ContentFrameStyle}" 
                    Source="/Home" Navigated="ContentFrame_Navigated" NavigationFailed="ContentFrame_NavigationFailed">
    <navigation:Frame.UriMapper>
        <uriMapper:UriMapper>
            <uriMapper:UriMapping Uri="/{pageName}/{id}" MappedUri="/Views/{pageName}.xaml?id={id}" />
            <uriMapper:UriMapping Uri="" MappedUri="/Views/Home.xaml"/>
            <uriMapper:UriMapping Uri="/{pageName}" MappedUri="/Views/{pageName}.xaml"/>
        </uriMapper:UriMapper>
    </navigation:Frame.UriMapper>
</navigation:Frame>

URL マッピングを利用した画面遷移のサンプルは以下の通りです。

サンプル:\MSStoreSample\ MSStoreSample \Views/Home.xaml.cs

 private void productListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
 DefaultColorProducts selectedProduct = productListBox.SelectedItem as DefaultColorProducts;
 NavigationService.Navigate(new Uri(String.Format("/Product/{0}", selectedProduct.ProductId), UriKind.RelativeOrAbsolute));
}

やはり4行目の、

NavigationService.Navigate(new Uri(String.Format("/Product/{0}", selectedProduct.ProductId), UriKind.RelativeOrAbsolute));

という箇所に注目してください。ここで下記のようなURLを指定することにより、

https://localhost:8033/MSStoreSample.Web/#/Product/9ea8dafc-1940-4eaa-a30e-4b18e54f5941

このような下記URLに変換されて実行されます。

https://localhost:8033/MSStoreSample.Web/#/Views/Product.xaml/?id=9ea8dafc-1940-4eaa-a30e-4b18e54f5941

なお、以前のエントリで、「Navigation Application」テンプレート用のStyleを紹介しましたので、こちらも合わせてご利用ご検討ください。

*但し、日本語Visual Studioでこれらのテンプレートを適用した場合、エンコーディングがANSIになってしまうことがあります。その場合にはビルドエラーが出ますので、メモ帳等で、直接対象となる*.xamlファイルを開いて、UTF-8で上書き保存してください。

Silverlight Toolkit の利用

本ソリューションサンプルでは、Silverlight Toolkit で提供されている、様々なコントロールを利用することにより、以下のUI機能を実現しています。

① WrapPanel の利用

WrapPanle コントロールを、ItemsPanelTemplate として利用することにより、折り返し可能なリストボックスを実現しています。

サンプル:\MSStoreSample\ MSStoreSample\Views/Home.xaml

 <navigation:Page.Resources>

<ItemsPanelTemplate x:Key="HorizonalWrapPanel">

<controlsToolkit:WrapPanel Orientation="Horizontal" />

</ItemsPanelTemplate>
バインディングの実装

次に、バインディングの実装について、です。

① 双方向バインドの利用

ソリューションサンプルでは、Siliverlight で提供されている双方向バインド機能を利用しています。

WCF RIA Services を利用する場合、実はDomain Service と、クライアント側で共有(コピー)されるエンティティはすでに INotifyPropertyChanged インタフェースを実装しています。したがって、UI(XAML) にてバインディングを設定することで、双方向バインドを実現することができます。これは別途続編のところでまたご紹介できればと思います。

サンプル: \MSStoreSample\MSStoreSample\Views\Product.xaml

 <TextBox  x:Name="quantityTextBox" 
 Grid.Row="5" Grid.Column="1"  
 Margin="8,8,0,8" HorizontalAlignment="Left" 
 VerticalAlignment="Center" Width="60" 
 Height="24" FontSize="14" 
 Text="{Binding Quantity, Mode=TwoWay}"
/>
入力検証の実装

Silverlight アプリケーションでは、上記バインディングの機能を利用して入力検証を行います。Tech・EdのT6-401のセッションでもご紹介しました通り、WCF RIA Services を利用する場合、Domain Service で定義するエンティティのメタデータクラスのプロパティ宣言に対して、属性を付与することにより、エンティティ検証処理を実装することができます。

エンティティメタデータの実装:

サンプル:\MSStoreSample\MSStoreSample.Web\Services\MSStoreSampleDomainService.metadata.cs

  [MetadataTypeAttribute(typeof(BasketItems.BasketItemsMetadata))]
public partial class BasketItems
{

    // This class allows you to attach custom attributes to properties
    // of the BasketItems class.
    //
    // For example, the following marks the Xyz property as a
    // required property and specifies the format for valid values:
    //    [Required]
    //    [RegularExpression("[A-Z][A-Za-z0-9]*")]
    //    [StringLength(32)]
    //    public string Xyz { get; set; }
    internal sealed class BasketItemsMetadata
    {

        // Metadata classes are not meant to be instantiated.
        private BasketItemsMetadata()
        {
        }

        …

        [Include]
        public Products Products { get; set; }

        [Required]
        [Range(1, 99, ErrorMessage = "数量は 1 - 99 の間で入力してください。")]
        public Nullable<int> Quantity { get; set; }

        public string Size { get; set; }

        public string Style { get; set; }

        public Nullable<decimal> SubTotal { get; set; }
    }
}

27行目の[Required]、[Range]あたりに注目してください。解説は、T6-401解説前半部分である、こちらもご参考に。

XAML での入力検証の定義: サンプル: \MSStoreSample\MSStoreSample\Views\Product.xaml

 <TextBox  x:Name="quantityTextBox" 
 Grid.Row="5" Grid.Column="1"  
 Margin="8,8,0,8" HorizontalAlignment="Left" 
 VerticalAlignment="Center" Width="60" 
 Height="24" FontSize="14" 
 Text="{Binding Quantity, Mode=TwoWay, NotifyOnValidationError=True, ValidatesOnDataErrors=True}"
/>

上記の宣言(6行目に注目)により、下記のような表示となります。

image

認証機能の実装

本ソリューションサンプルでは Silverlight Business Application テンプレートに含まれる標準の認証機能を利用しています。標準の認証機能は ASP.NET Membership Provider をベースに実装されていますが、独自に拡張を行うことも可能です。

以上です。次回は、第3回から第11回までのポイント解説をお送りします。

鈴木 章太郎