なんとなく、こんな感じかな~と思ったのでメモってみる。
因みに、なんとなく思っただけで、実際にこのカタチで業務アプリを組んだこと無いので、誰か試してくれたら嬉しいな♪
前提条件
全体的な雰囲気としては
- ブラウザの戻るボタンは押されたくない
- アプリケーションのダウンロード時間は、初回は仕方ないとしても、二回目とか三回目のアクセスはそれなりの速さがいいな
- 画面は、普通のWebアプリみたいに画面遷移していくのが望ましい
- 画面の全体の大枠は、全ページ共通にしたいな
といった感じ。早速、大枠を作ってみよう。
プロジェクトを作成
さくっとSilverlightアプリケーションのプロジェクトを作成します。
因みに、画面遷移はするけど、Silverlight ナビゲーション アプリケーションでは作りません。
Silverlight ナビゲーション アプリケーションは、微妙に作りこまれてる雛形になってるので、それを把握して、いらない部分を削り取るのがメンドクサイので、ナビゲーションするアプリケーションを作るときも、普通のSilverlight アプリケーションをベースにしたほうが、個人的にラクチンです。
とりあえず、「SLBizApp」という名前で作成しました。
SLBizAppの参照に、System.Windows.Controls.Navigation.dllを追加します。
これで、画面遷移に必要なライブラリが追加されます。
アプリケーション ライブラリ キャッシュの有効化
SLBizAppのプロパティを開いて、Silverlightタブにある「アプリケーション ライブラリ キャッシュを使用してXAPを縮小する」にチェックを入れておきます。
これで、ビルドするとSystem.Windows.Controls.Navigation.zipがSLBizApp.WebプロジェクトのClientBinに作られます。
アプリケーションの画面のレイアウトを決める
ここらへん、各アプリによってどんな感じにするのか変わってくると思うので、ここでは適当にします。
ざっくりと、GridのRowDefinitionあたりで、全体のレイアウトをざっくり切ります。ざっくり切ったところに、Gridを置いて、大枠にします。
<UserControl xmlns:dataInput="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data.Input" x:Class="SLBizApp.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:DesignWidth="640" d:DesignHeight="480">
<Grid x:Name="LayoutRoot">
<Grid.RowDefinitions>
<!-- ヘッダー -->
<RowDefinition Height="Auto" />
<!-- 余白 -->
<RowDefinition Height="5" />
<!-- コンテンツ -->
<RowDefinition Height="*" />
<!-- フッター -->
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<!-- ヘッダー -->
<Grid Grid.Row="0">
<TextBlock Text="なんとかシステム" FontSize="24" />
</Grid>
<!-- コンテンツ -->
<Grid Grid.Row="2">
<!-- TODO : これから作る -->
</Grid>
<!-- フッター -->
<Grid Grid.Row="3">
<StackPanel>
<dataInput:ValidationSummary Height="25" />
<TextBlock Text="こぴーらいととか" TextAlignment="Right"/>
</StackPanel>
</Grid>
</Grid>
</UserControl>
コンテンツの部分は、Frameを置きます。
<!--
名前空間を定義しておく
xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"
xmlns:uriMapper="clr-namespace:System.Windows.Navigation;assembly=System.Windows.Controls.Navigation"
-->
<!-- コンテンツ -->
<Grid Grid.Row="2">
<navigation:Frame JournalOwnership="OwnsJournal">
<navigation:Frame.UriMapper>
<uriMapper:UriMapper>
<uriMapper:UriMapping Uri="" MappedUri="/Views/LoginPage.xaml" />
<uriMapper:UriMapping Uri="/Menu" MappedUri="/Views/MenuPage.xaml" />
<uriMapper:UriMapping Uri="/{bizName}/{pageName}" MappedUri="/{bizName}/Views/{pageName}Page.xaml" />
</uriMapper:UriMapper>
</navigation:Frame.UriMapper>
</navigation:Frame>
</Grid>
最初にログインページが表示されて、/Menuで、/Views/MenuPage.xamlに遷移して、/業務名/ページ名っていう感じのURLで/業務名/Views/ページ名Page.xamlに遷移するといった定義を追加してます。
JournalOwnershipにOwnsJournalを設定することで、Frame内のページが遷移しても、ブラウザの履歴に残らないようにします。
これで、大枠は完成です。
ログイン画面とメニュー画面
次に、システム全体で共通のログイン画面とメニュー画面を作っていきます。
SLBizAppにViewsという、フォルダを作成して、そこにLoginPage.xamlとMenuPage.xamlを作成します。
今回は、どんがらなので、ログインのロジックは無しにしてHyperlinkButtonを押せば、問答無用で、メニュー画面に移動するようにしました。
途中でLabelコントロールを使用しているので、System.Windows.Controls.Data.Input.dllを参照に追加しておきます。
LoginPage.xaml
<navigation:Page xmlns:dataInput="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data.Input" x:Class="SLBizApp.Views.LoginPage"
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"
xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"
d:DesignWidth="640" d:DesignHeight="480"
Title="LoginPage Page">
<StackPanel x:Name="LayoutRoot">
<dataInput:Label Content="ユーザ名" IsRequired="True"></dataInput:Label>
<TextBox />
<dataInput:Label Content="パスワード" IsRequired="True"></dataInput:Label>
<PasswordBox />
<HyperlinkButton Content="ログイン" NavigateUri="/Menu" />
</StackPanel>
</navigation:Page>
次に、メニュー画面です。
これも業務Aと業務Bの画面にそれぞれ遷移するだけのシンプルなものにしました。
MenuPage.xaml
<navigation:Page x:Class="SLBizApp.Views.MenuPage"
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"
xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"
d:DesignWidth="640" d:DesignHeight="480"
Title="メニュー画面">
<StackPanel x:Name="LayoutRoot">
<HyperlinkButton Content="業務A" NavigateUri="/BizA/Top" />
<HyperlinkButton Content="業務B" NavigateUri="/BizB/Top" />
</StackPanel>
</navigation:Page>
この時点で、実行するとログイン画面が出て、ログインのリンクを押すと、メニュー画面に飛びます。
業務固有の画面を作っていく
ここから量産体制に入ります。
SLBizApp.BizAという名前で、Silverlight クラス ライブラリを作成します。
そこに、Viewsフォルダを作成して、ユーザコントロールをTopView.xamlという名前で作成します。
TopView.xamlは、業務Aの画面ということがわかればいいので、超手抜きです。
<UserControl x:Class="SLBizApp.BizA.Views.TopView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid x:Name="LayoutRoot" Background="White">
<TextBlock Text="業務Aの画面" />
</Grid>
</UserControl>
次に、このユーザコントロールをホストする、PageをSLBizAppプロジェクトに作成します。SLBizAppの参照にSLBizApp.BizAプロジェクトを追加します。そして、SLBizAppに、BizAというフォルダを作成して、その下にViewsというフォルダを作成します。
その中にTopPage.xamlという名前で、Silverlightページを作成します。
TopPage.xamlは、TopViewユーザコントロールを持つだけのシンプル設計にします。
<navigation:Page x:Class="SLBizApp.BizA.Views.TopPage"
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"
xmlns:bizaViews="clr-namespace:SLBizApp.BizA.Views;assembly=SLBizApp.BizA"
mc:Ignorable="d"
xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"
d:DesignWidth="640" d:DesignHeight="480"
Title="業務Aのトップページ">
<bizaViews:TopView />
</navigation:Page>
この時点で実行すると、ログイン → メニュー → 業務Aの画面といった感じで画面が遷移していくものになっています。
いい感じ。
あとは、業務B関連のものを同じ要領でつくっていきます。
詳しい手順は、説明しませんが、業務Aと同じ要領で作ったら、ソリューションエクスプローラは以下のような感じになると思います。
業務単位のプロジェクトのアプリケーション ライブラリ キャッシュの構成を行う
最後の仕上げとして、業務単位で作ってるプロジェクトに対して、アプリケーションライブラリキャッシュを有効化していきます。
各BizAのプロジェクトの直下に、SLBizApp.BizA.extmap.xmlという名前のXMLファイルを作成します。
中身を、以下のように編集します。
<?xml version="1.0"?>
<manifest xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<assembly>
<name>SLBizApp.BizA</name>
<version>*</version>
<publickeytoken>*</publickeytoken>
<relpath>SLBizApp.BizA.dll</relpath>
<extension downloadUri="SLBizApp.BizA.zip" />
</assembly>
</manifest>
そして、このファイルのプロパティから「出力ディレクトリに」の項目を「常にコピーする」に変更します。
同じ手順をBizBのほうにも行います(BizAとなっている部分は適時BizBに置き換える)
この状態でビルドすると、SLBizApp.WebプロジェクトのClientBinフォルダの下が以下のようになります。
まとめ
こんな感じで、システムを組んでいくと、
SLBizAppプロジェクトは、ログイン画面・メニュー画面・各業務画面(ユーザコントロール)をホストするPageだけで構成されるので、サイズは、そんなに肥大化しないはずです。
業務に仕様変更があった場合は、業務単位のアセンブリのzipファイルが個別にダウンロードされ、アプリ全体がダウンロードしなおしっていうことにはならないです。
ということで、こんな雰囲気で組んでいったら、ちょっと大きめのシステムになっても、xapが肥大化しすぎてたまらん!っていう事態には、なりにくいんじゃないだろうかと考えてみました。
以上です。