実例で学ぶアプリケーション開発 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に変換されて実行されます。
なお、以前のエントリで、「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行目に注目)により、下記のような表示となります。
認証機能の実装
本ソリューションサンプルでは Silverlight Business Application テンプレートに含まれる標準の認証機能を利用しています。標準の認証機能は ASP.NET Membership Provider をベースに実装されていますが、独自に拡張を行うことも可能です。
以上です。次回は、第3回から第11回までのポイント解説をお送りします。
鈴木 章太郎