「[[マイクロソフト系技術情報 Wiki>http://techinfoofmicrosofttech.osscons.jp/]]」は、「[[Open棟梁Project>https://github.com/OpenTouryoProject/]]」,「[[OSSコンソーシアム .NET開発基盤部会>https://www.osscons.jp/dotNetDevelopmentInfrastructure/]]」によって運営されています。

-[[戻る>XAML]]
--[[XAMLの書き方(1)]]
--XAMLの書き方(2)

* 目次 [#s57b8ef1]
#contents

*概要 [#k46d718e]
[[XAMLの書き方(1)]]の続き。

*ビルティング ブロック クラス [#ybf1a413]
[[WPF]] / [[Silverlight]]は、[[Windows Forms]]とは全く異なるUIサブシステムであるが、~
類似のビルティング ブロック クラスが使用されているため、よく似たコードでプログラムを記述することができる。

**Applicationオブジェクト [#xbfab659]
[[WPF]] / [[Silverlight]]にはWindows フォームと同様に Applicationオブジェクトが存在する。

-参考
--MSDN > .NET Frameworkクラス ライブラリ
---> System.Windows.Applicationクラス~
http://msdn.microsoft.com/ja-jp/library/system.windows.application.aspx

***画面の起動 [#u2efda8f]
-[[WPF]]では、ApplicationオブジェクトのStartupUri 属性に起動時に呼び出されるXAMLを指定する。
-Applicationオブジェクトはメッセージ ループを構築し、アプリケーションが終了するまでの間、ユーザにイベントを問い合わせる。
-なお、この処理は、起動時に呼び出されるXAMLのパーシャル クラスに自動生成されるので通常は確認できない。

 <Application x:Class="WpfApplication1.App"
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   StartupUri="Window1.xaml">
   <Application.Resources></Application.Resources>
 </Application>

-なお、[[Silverlight]]では、ApplicationオブジェクトのStartupUri属性がサポートされないので、~
[[Application.Startupイベント(後述)>#r4f6dfc7]]から、初期画面を起動する。

-参考
--MSDN > .NET Frameworkクラス ライブラリ
---> System.Windows.Application.StartupUriプロパティ~
http://msdn.microsoft.com/ja-jp/library/system.windows.application.startupuri.aspx

***イベント [#r4f6dfc7]
Applicationオブジェクトには様々なイベント処理を実装することができる。

-開始イベント~
[[WPF]] / [[Silverlight]]での共通初期化処理を実装する場合、Application.Startup イベントを使用する。

-共通エラー ハンドリング イベント~
[[WPF]] / [[Silverlight]]での共通エラー ハンドリング処理を実装する場合、~
Application.DispatcherUnhandledException イベントで例外をハンドルする。
[[Application.DispatcherUnhandledException>https://opentouryo.osscons.jp/index.php?%E4%BE%8B%E5%A4%96%E5%87%A6%E7%90%86%E6%96%B9%E5%BC%8F#qee70f28]]イベントで例外をハンドルする。

-終了イベント~
[[WPF]] / [[Silverlight]]での共通終了処理を実装する場合、Application.Exit イベントを使用する。

-イベントの実装サンプル~
以下、それぞれのイベントの実装サンプルである。
--XAML
 <Application x:Class="WpfApplication1.App"
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
     StartupUri="Window1.xaml"
     Startup="Application_Startup" Exit="Application_Exit"
     DispatcherUnhandledException="Application_DispatcherUnhandledException">
     <Application.Resources></Application.Resources>
 </Application>
--コード ビハインド
 private void Application_Startup(object sender, StartupEventArgs e) {
   System.Diagnostics.Debug.WriteLine("開始処理");
 }
 
 private void Application_DispatcherUnhandledException(
   object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e) {
   System.Diagnostics.Debug.WriteLine("エラー処理");
 }
 
 private void Application_Exit(object sender, ExitEventArgs e) {
   System.Diagnostics.Debug.WriteLine("終了処理");
 }

-参考
--MSDN > .NET Frameworkクラス ライブラリ > System.Windows.Application
---> Startupイベント~
http://msdn.microsoft.com/ja-jp/library/system.windows.application.startup.aspx
---> DispatcherUnhandledExceptionイベント~
http://msdn.microsoft.com/ja-jp/library/system.windows.application.dispatcherunhandledexception.aspx
---> Exitイベント~
http://msdn.microsoft.com/ja-jp/library/system.windows.application.exit.aspx

***Application.Propertiesプロパティ [#w557dfc3]
-[[WPF]]ではASP.NETなどのWebアプリケーションと同様のSession変数ライクな~
Key - Valueストアとして、Application.Properties プロパティを利用可能である。

-以下のサンプルで、任意の個所で(画面間を跨って)~
Application.Propertiesプロパティが取得できることを確認できる。
--Application.xaml.cs
---XAML
 private void Application_Startup(object sender, StartupEventArgs e) {
   Application.Current.Properties["Key"] = "Value1";
 }

--Window1.xaml.cs
---XAML
 <Window x:Class="WpfApplication1.Window1"
   ・・・
   Loaded="Window_Loaded">
 <Grid>
   <Button Click="Button_Click">ボタン</Button>
 </Grid>

---コード ビハインド
 private void Window_Loaded(object sender, RoutedEventArgs e) {
   MessageBox.Show((string)Application.Current.Properties["Key"]);
   Application.Current.Properties["Key"] = "Value2";
 }
 
 private void Button_Click(object sender, RoutedEventArgs e) {
   Window2 w2 = new Window2();
   w2.Show();
 }

--Window2.xaml.cs
---コード ビハインド
 private void Window_Loaded(object sender, RoutedEventArgs e) {
   MessageBox.Show((string)Application.Current.Properties["Key"]);
 }

-参考
--MSDN > .NET Frameworkクラス ライブラリ
---> System.Windows.Application.Propertiesプロパティ~
http://msdn.microsoft.com/ja-jp/library/system.windows.application.properties.aspx

**Window画面 [#y123c6bc]

-参考
--MSDN > .NET Frameworkクラス ライブラリ
---> System.Windows.Windowクラス~
http://msdn.microsoft.com/ja-jp/library/system.windows.window.aspx

***ウィンドウの起動 [#ye034fea]
[[WPF]]では[[Windows Forms]]と同様にWindow 画面を、以下のように起動できる(「[[XBAP]]」を除く)。

-モードレス(通常画面)の起動~
モードレス(通常画面)として起動。
 Window2 win2 = new Window2();
 win2.Show();

-モーダル ダイアログの起動~
モーダル ダイアログとして起動。
 Window2 win2 = new Window2();
 win2.Owner = this;
 win2.ShowDialog();

***プロパティ [#o7a9e70b]
Windowには、以下のようなプロパティを設定できる。

-Title~
Window.Title プロパティは、ウィンドウのタイトルを取得 / 設定する。

-WindowStartUpLocation~
Window. WindowStartUpLocation プロパティは、~
ウィンドウ起動時の表示位置を取得 / 設定する。

-ResizeMode~
Window. ResizeMode プロパティは、ウィンドウの~
サイズ変更モードを取得 / 設定する(ResizeMode 列挙体)。

-WindowStyle~
Window. WindowStyle プロパティは、~
ウィンドウの境界線スタイルを取得 / 設定する。

-ShowInTaskbar~
Window. ShowInTaskbar プロパティは、~
タスクバーのアイコンの表示・非表示を取得 / 設定する。

-参考
--MSDN > .NET Frameworkクラス ライブラリ > System.Windows.Window
---> Titleプロパティ~
http://msdn.microsoft.com/ja-jp/library/system.windows.window.title.aspx
---> WindowStartupLocationプロパティ~
http://msdn.microsoft.com/ja-jp/library/system.windows.window.windowstartuplocation.aspx
---> ResizeModeプロパティ~
http://msdn.microsoft.com/ja-jp/library/system.windows.window.resizemode.aspx
---> WindowStyleプロパティ~
http://msdn.microsoft.com/ja-jp/library/system.windows.window.windowstyle.aspx
---> ShowInTaskbarプロパティ~
http://msdn.microsoft.com/ja-jp/library/system.windows.window.showintaskbar.aspx

**ナビゲーション フレームワーク [#cb2f10e1]
-[[WPF]] / [[Silverlight]]では「ナビゲーション フレームワーク」によりASP.NETなどのWebアプリケーションと同様に、~
WWWブラウザの単一ウィンドウ、複数ページから構成される画面を提供できる。

-この機能は、「ナビゲーション フレームワーク」のNavigationWindow / Pageにより提供され、~
ウィザードや、ハイパー テキスト ソリューションに有用である。

-なお、以下のような機能もサポートされている。
--WWWブラウザ型の単一ウィンドウ、複数ページから構成される画面を提供
--WWWブラウザ同様、画面遷移の履歴が残り[進む]・[戻る]操作に対応
--ハイパーリンクによる画面遷移、HTTPコンテンツの参照をサポート

-以下、NavigationWindow / Pageの使用方法を説明する。

***NavigationWindow画面を作成 [#q77831fb]
-[[WPF]]の場合、初めに、NavigationWindow (を継承した)画面(ここではNavWindowクラス)を作成する。
-なお、NavigationWindowは、Windowクラスを継承するため、前述のプロパティを設定可能である。

-コード
--XAML
 <NavigationWindow x:Class="WpfApplication1.NavWindow"
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   Title="NavWindow" Height="300" Width="300">
 </NavigationWindow>
--コード ビハインド
 public partial class NavWindow : NavigationWindow {
   public NavWindow() {
     InitializeComponent();
   }
 }

-参考
--MSDN > .NET Frameworkクラス ライブラリ
---> System.Windows.Navigation.NavigationWindowクラス~
http://msdn.microsoft.com/ja-jp/library/system.windows.navigation.navigationwindow.aspx

***NavigationWindow画面を起動 [#zcc2c387]
[[WPF]]でNavigationWindow画面を起動する方法について説明する。

-モードレス(通常画面)~
NavigationWindow画面をモードレス(通常画面)として起動できる。~
なお、ApplicationオブジェクトのStartupUri属性から直接起動することもできる。
 NavWindow normalWindow = new NavWindow();
 normalWindow.Show();

-モーダル ダイアログ~
NavigationWindow画面をモーダル ダイアログとして起動することもできる。
 NavWindow dialogWindow = new NavWindow(); 
 dialogWindow.Owner = this; 
 bool returnValue = dialogWindow.ShowDialog() ?? false;

***Page画面のロード (1) [#cfddd8c0]
-[[WPF]]でNavigationWindow画面から、Page 画面をロードする方法について説明する。

-なお、PageはFrameworkElementからの派生クラスであって、~
NavigationWindow・Frame コントロールでのみホスト・ナビゲーションができる。

-Page 画面をロードする方法

--Loadedイベントからロード~
NavigationWindow画面のコード ビハインドのLoadedイベントからPage画面をロードする。
---XAML
 <NavigationWindow x:Class="WpfApplication1.NavWindow"
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
     Title="NavWindow" Height="300" Width="300" Loaded="NavigationWindow_Loaded">
 </NavigationWindow>
---コード ビハインド
 public partial class NavWindow : NavigationWindow {
   public NavWindow() {
     InitializeComponent();
   }
   private void NavigationWindow_Loaded(object sender, RoutedEventArgs e) {
     // Page1 を表示します。
     this.Navigate(new Page1());
   }
 }

--Sourceプロパティからロード~
NavigationWindow画面のSourceプロパティに指定してPage画面をロードすることもできる。
---XAML
 <NavigationWindow x:Class="WpfApplication1.NavWindow"
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   Title="NavWindow" Height="300" Width="300" Source="Page1.xaml">
 </NavigationWindow>

--Frameコントロールからロード~
Page内を複数のFrameに分割し、その中に複数のページをロードすることもできる。
---XAML
 <StackPanel Orientation="Vertical">
   <Frame Source="Page2.xaml" Navigated="Frame1_Navigated"/>
   <Frame Source="Page3.xaml" Navigated="Frame2_Navigated"/>
 </StackPanel>

--StartupUri属性からロード~
[[ApplicationオブジェクトのStartupUri属性から直接Page画面をロードすることもできる>#u2efda8f]]~
(もしくは、[[前述のApplication.Startupイベント>#r4f6dfc7]]から起動する)。

-参考
--MSDN > .NET Frameworkクラス ライブラリ
---> System.Windows.Controls.Frameクラス~
http://msdn.microsoft.com/ja-jp/library/system.windows.controls.frame.aspx
---> System.Windows.Navigation.NavigationWindowクラス~
http://msdn.microsoft.com/ja-jp/library/system.windows.navigation.navigationwindow.aspx

***Page画面のロード (2) [#yc0b57e1]
「[[XBAP]]」、「[[Silverlight]]」では、WindowNavigation / Windowが使用出来ないため、以下の方法で、直接Page画面をロードする。

-[[XBAP]]~
ApplicationオブジェクトのStartupUri属性から直接Page画面をロードする。
 <Application x:Class="WpfBrowserApplication1.App"
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
     StartupUri="Page1.xaml">
     <Application.Resources>
     </Application.Resources>
 </Application>

-[[Silverlight]]~
ApplicationオブジェクトのStartupUri属性がサポートされないので、~
Application.StartupイベントからPage画面をロードする。
--XAML
 <Application xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
              x:Class="SilverlightApplication1.App">
     <Application.Resources> 
     </Application.Resources>
 </Application>
--コード ビハインド
 public App(){
   this.Startup += this.Application_Startup;
   this.Exit += this.Application_Exit;
   this.UnhandledException += this.Application_UnhandledException;
 
   InitializeComponent();
 }
 
 private void Application_Startup(object sender, StartupEventArgs e) {
   // this.RootVisual = new MainPage(); デフォルトは、ユーザコントロール
   this.RootVisual = new Page1();
 }

>なお、「[[Silverlight]]」では、~
デフォルトの初期画面(Application.RootVisual)が、ユーザ コントロールとなっているため、~
通常、ユーザ コントロールにFrameを追加し、Frameでページ遷移させる方法を取る。

***Page画面の画面遷移 [#gd2f5a43]
[[WPF]] / [[Silverlight]]におけるPage画面の画面遷移方法について説明する。

-Hyperlinkタグによる画面遷移
--[[WPF]]のPage画面では、Hyperlinkタグ使用して、画面遷移できる。~
※ なお、Hyperlinkタグは、TextBlockタグなどで囲う必要がある。
 <Hyperlink NavigateUri="Page2.xaml">次のページへ移動します。</Hyperlink>
 <Hyperlink NavigateUri="Page1.xaml">前のページへ移動します。</Hyperlink>

--[[Silverlight]]のPage画面では、HyperlinkButtonタグ使用して、画面遷移できる。
 <HyperlinkButton NavigateUri="/Page2.xaml">次のページへ移動します。</HyperlinkButton>
 <HyperlinkButton NavigateUri="/Page1.xaml">前のページへ移動します。</HyperlinkButton>

-コードビハインドからの画面遷移~
コード ビハインドからの画面遷移も可能である。
--[[WPF]]の場合は、Page画面を直接生成可能である。
 this.NavigationService.Navigate(new Page2());
--[[Silverlight]]の場合は、Page画面をUriで指定する必要がある。
---以下は、相対パス指定:
 this.NavigationService.Navigate(new Uri("/Page2.xaml", UriKind.Relative));
---以下は、絶対パス指定:
 this.NavigationService.Navigate(
      new Uri("pack://application:,,,/Page2.xaml", UriKind.Absolute));

***Page画面の進む・戻る操作への対応 [#jc2ad1b0]
-[[WPF]] / [[Silverlight]]では、WWWブラウザ同様、進む・戻るボタンが常備されており、~
進む・戻る操作に対応している(Webアプリケーションと同様に、戻った際は、前ページの入力の状態は保持されている)。

-「[[XBAP]]」、「[[Silverlight]]」については、この進む・戻るボタンは、WWWブラウザのものと統合されている(同じボタンを利用する)。

#ref(NavigationServiceGoForwardAndGoBack.png,left,nowrap,進む・戻るボタン)

-コードビハインドからの進む・戻る操作~
コードビハインドからは、次の処理で進む・戻る操作に対応できる。
--進む
 this.NavigationService.GoForward();
--戻る
 this.NavigationService.GoBack();

-履歴の管理
--進む・戻る操作が行えるということは、画面遷移の履歴を保持しているということである。
---これを以下のコードで画面遷移のPage履歴を消去できる。
 this.NavigationService.RemoveBackEntry();
---Page履歴の消去処理を自動化する場合は、NavigationWindowのNavigatedイベントで実行すると良い。
 private void NavigationWindow_Navigated(object sender, NavigationEventArgs e) {
   this.NavigationService.RemoveBackEntry();
 }

--「[[XBAP]]」、「[[Silverlight]]」ではNavigationWindowが存在しないため、FrameのNavigatedイベントで実行する。~
※ Frameを使用しない場合は、PageのLoadedイベントなどで履歴を消去する。
 private void Frame1_Navigated(object sender, NavigationEventArgs e) {
   if (NavigationService !=null) {
     if (NavigationService.CanGoBack) {
       this.NavigationService.RemoveBackEntry();
     }
   }
 }
 
 private void Frame2_Navigated(object sender, NavigationEventArgs e) {
   if (NavigationService != null) {
     if (NavigationService.CanGoBack) {
       this.NavigationService.RemoveBackEntry();
     }
   }
 }

-なお、Page履歴の管理はブラック ボックスとなっているため、~
詳細は不明であるが、前Pageに戻った際に入力状態が保持されていることから、~
Page履歴により、ある程度メモリが消費されているものと考える。~
メモリ消費量が拡大するような場合はPage履歴の消去を検討する。

***Page画面の進む・戻る操作の注意点 [#j89c6ca2]
- [新規画面遷移] → [戻る] → [進む]の一連の操作で、表示されるPageの再初期化が発生するので、~
必要に応じてこれを考慮した実装とするか、[進む]・[戻る]操作を抑止する必要がある。

-再初期化とは?~
コンストラクタや、PageのLoadedイベントの処理の実行
--コンストラクタが実行されるのは、最初のPageのみである。
--LoadedイベントはすべてのPageで実行される。

- [進む]・[戻る]操作を抑止する。~
先頭PageでPage.ShowsNavigationUIプロパティをfalseに設定にし、~
以降のPageの[進む]・[戻る]ボタンを非表示にするか、前述の履歴消去で対応する。

-[進む]・[戻る]ボタンを非表示にする。
--XAML
 <Page x:Class="WpfApplication1.Page1"
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   Title="Page1" ShowsNavigationUI="false">

-BackSpaceキーによる[戻る]を抑止
--[進む]・[戻る]ボタンを非表示にする場合もBackSpaceキーで戻ることができるので、必要に応じてBackSpaceキーを抑止する。
--また、UI要素にフォーカスの当たっていない状態では、BackSpaceキーを抑止することができないので、~
Page.LoadedイベントなどでPage上の入力UI要素にフォーカスを当てるようにする。
---XAML
 <Page x:Class="WpfApplication1.Page1"
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   Title="Page1" ShowsNavigationUI="false"
   Loaded="Page_Loaded" KeyDown="Page_KeyDown">
   <StackPanel>
     <TextBlock>
       <Hyperlink NavigateUri="Page2.xaml">Page2</Hyperlink>
     </TextBlock>
     <TextBox Name="textBox1"/>
   </StackPanel>
 </Page>

---コード ビハインド
 public partial class Page1 : Page {
   public Page1() {
     InitializeComponent();
   }
   private void Page_Loaded(object sender, RoutedEventArgs e) {
     this.textBox1.Focus();
   }
   private void Page_KeyDown(object sender, KeyEventArgs e) {
     if (e.Key == Key.Back) e.Handled = true;
   }
 }

***その他 [#a491ed54]
NavigationWindow / Pageのその他のトピック

-UriMapperクラス

--UriMapper クラスは「[[Silverlight]]」専用のコントロールになるが、~
HyperlinkタグのNavigateUri属性などで使用するPage.xamlへのパスを簡素化することができる。

--UriMapperクラスは複数のUriMapping クラスから構成され、~
UriMappingクラスのMappedUriプロパティに実際のPage.xamlへのパス(のパターン)を指定、~
Uriプロパティに簡素化したパス(のパターン)を指定する。

--作成したUriMapperオブジェクトをFrame.UriMapperプロパティに~
追加することで、Frame内で簡素化したパスを使用することができる。

-ChildWindowコントロール

--ChildWindow コントロールは、「[[Silverlight]]」専用のコントロールであるが、~
Page上に、子ウィンドウ(モーダル ダイアログ相当)を表示できる。

--「[[Silverlight]]」アプリケーションのプロジェクトでは、~
ChildWindowのクラステンプレートが用意されており、~
これを新規作成し、以下のコードでChildWindowを呼び出すことができる。

--ChildWindowは、若干のアニメーションのエフェクトを伴い表示される。~
また、ChildWindowから、さらに子のChildWindowを表示させることもできる。
 ChildWindow1 childWindow = new ChildWindow1();
 childWindow.Show();

-注意事項~
なお、NavigationWindow / Pageの使用における注意点は、以下を参照のこと。
--「[[XBAP]]」の場合の[[注意点>XBAP#cc3b3e1b]]
--「[[Silverlight]]」の場合の[[注意点>Silverlight]]

-ナビゲーション フレームワーク 参考情報
--MSDN > Silverlight > アプリケーション モデルとプログラミング モデル
---> アプリケーション モデル > ナビゲーションの概要~
http://msdn.microsoft.com/ja-jp/library/cc838245.aspx#application_navigation
--@IT > Insider.NET > 連載:Silverlight 3実践プログラミング
---> ナビゲーション・フレームワークとChildWindowコントロール~
1. ナビゲーション・フレームワークとは~
http://www.atmarkit.co.jp/fdotnet/chushin/silverlight3develop_01/silverlight3develop_01_01.html
--CodeZine > Silverlight 3徹底入門
---> Silverlight 3で作る業務アプリケーションの要 > 「ナビゲーションフレームワーク」~
http://codezine.jp/article/detail/4810
 
-参考
--MSDN > .NET Frameworkクラス ライブラリ
---> System.Windows.Navigation.UriMapperクラス~
http://msdn.microsoft.com/ja-jp/library/system.windows.navigation.urimapper.aspx
---> System.Windows.Navigation.UriMappingクラス~
http://msdn.microsoft.com/ja-jp/library/system.windows.navigation.urimapping.aspx
--->System.Windows.Controls.ChildWindowクラス~
http://msdn.microsoft.com/ja-jp/library/system.windows.controls.childwindow.aspx

**Win32ダイアログ [#m8eadb88]
-[[WPF]] / [[Silverlight]]は、従来からの種々のWin32ダイアログをサポートしている(一部サポートされないダイアログもある)。

-このため、[[WPF]] / [[Silverlight]]アプリケーションであるからと言って、~
「外観や、操作方法の異なる標準ダイアログに慣れる必要がある」・・・といった問題は無い。

***メッセージ ボックス [#u8a19670]
下記のMessageBoxクラスの名前空間は、[[Windows Forms]]ではなく[[WPF]]のものだが、~
このMessageBoxクラスのクラス階層を確認すると[[WPF]]のアーキテクチャに基づいていないことが確認できる。

-MSDN > .NET Frameworkクラス ライブラリ > System.Windows.Messageboxクラス~
http://msdn.microsoft.com/ja-jp/library/system.windows.messagebox.aspx
-MSDN > Silverlightの.NET Frameworkクラス ライブラリ > System.Windows.Messageboxクラス~
http://msdn.microsoft.com/ja-jp/library/system.windows.messagebox(VS.95).aspx

***コモン ダイアログ ボックス [#j9729fdc]
-OpenFileDialog クラス
--OpenFileDialogは、部分信頼で実行されている。
--「[[XBAP]]」・「[[Silverlight]]」でもファイル名を取得できる。

-SaveFileDialog クラス
--SaveFileDialogは、部分信頼で実行されている。
--「[[XBAP]]」・「[[Silverlight]]」でもファイルを保存できる。

-PrintDialog クラス
---このクラスの名前空間は、[[Windows Forms]]ではなく[[WPF]]のものだが、~
クラス階層を確認するとWPFのアーキテクチャに基づいていないことが確認できる。
---Silverlightでは、Printdocument クラス

-参考
--MSDN > .NET Frameworkクラス ライブラリ
---> Microsoft.Win32.OpenFileDialogクラス~
http://msdn.microsoft.com/ja-jp/library/microsoft.win32.openfiledialog.aspx
---> Microsoft.Win32.SaveFileDialogクラス~
http://msdn.microsoft.com/ja-jp/library/microsoft.win32.savefiledialog.aspx
---> System.Windows.Controls.PrintDialogクラス~
http://msdn.microsoft.com/ja-jp/library/system.windows.controls.printdialog.aspx

--MSDN > Silverlightの.NET Frameworkクラス ライブラリ 
---> System.Windows.Controls.OpenFileDialogクラス~
http://msdn.microsoft.com/ja-jp/library/system.windows.controls.openfiledialog(VS.95).aspx
---> System.Windows.Controls.SaveFileDialogクラス~
http://msdn.microsoft.com/ja-jp/library/system.windows.controls.savefiledialog(VS.95).aspx
---> System.Windows.Printing.PrintDocumentクラス~
http://msdn.microsoft.com/ja-jp/library/system.windows.printing.printdocument(VS.95).aspx

--MSDN > Windows Presentation Foundation > ドキュメント
---> 印刷および印刷システムの管理 > 印刷の概要~
http://msdn.microsoft.com/ja-jp/library/ms742418(VS.80).aspx

***カスタム ダイアログ ボックス [#r16cb2d2]
-[[前述の、モーダル ダイアログの起動>#ye034fea]]を参照のこと。
-「[[XBAP]]」では使用できないので注意する。
-なお、「[[Silverlight]]」の場合は、前述のChildWindowコントロールで代替可能である。

***参考 [#qe69230a]
-MSDN > Windows Presentation Foundation
--> アプリケーション開発 > WPFウィンドウ > ダイアログ ボックスの概要~
http://msdn.microsoft.com/ja-jp/library/aa969773.aspx
--> 移行と相互運用性 > Windowsフォーム コントロールおよび同等のWPFコントロール~
http://msdn.microsoft.com/ja-jp/library/ms750559.aspx
-MSDN > Silverlight
--> コントロールおよびダイアログ ボックスの使用 > ダイアログ ボックスの概要~
http://msdn.microsoft.com/ja-jp/library/ff382752(VS.95).aspx

*入力支援 [#j81696d4]
入力支援機能に関する技術要素について説明する。

**メニュー・タスクバーとコマンド [#p7757f04]
-メニュー・タスクバーと「コマンド」の関連付けも、宣言的プロパティにより実装・カスタマイズ可能。
-例えば、以下のXAMLでメニュー・タスクバーと「コマンド」の概要を理解することができ、~
また、メニュー・タスクバーと「コマンド」の関連付けが容易に実装可能であることが分かる。

***実装 [#r1e0aba4]
-画面
#ref(Menu_Taskbar_Command.png,left,nowrap,メニュー・タスクバーとコマンド)

-XAML
 <Window.CommandBindings>
   <!--ApplicationCommands.Saveのカスタム動作(実行可否、イベント処理)を実装する-->
   <CommandBinding x:Name="SaveCommand"
     Command="ApplicationCommands.Save"
     CanExecute="SaveCommand_CanExecute"
     Executed="SaveCommand_Executed"/>
   <!--ApplicationCommands.Closeのカスタム動作(実行可否、イベント処理)を実装する-->
   <CommandBinding x:Name="CloseCommand"
     Command="ApplicationCommands.Close"
     CanExecute="CloseCommand_CanExecute"
     Executed="CloseCommand_Executed"/>
 </Window.CommandBindings>
 
 <DockPanel>
   <Menu DockPanel.Dock="Top">
     <MenuItem Header="ファイル(_F)">
       <!--ApplicationCommands.Save → カスタム動作 → CommandBinding-->
       <MenuItem Header="保存(_S)" Command="ApplicationCommands.Save">
         <MenuItem.Icon><Image Source=".\icons\save.png"/></MenuItem.Icon>
       </MenuItem>
       <Separator/>
       <!--ApplicationCommands.Close → カスタム動作 → CommandBinding-->
       <!--MenuItem Header="終了(_X)" Command="ApplicationCommands.Close"-->
       <!--ApplicationCommands.Close → カスタム動作 → カスタムイベント-->
       <MenuItem Name="Exit" Click="Exit_Click"  Header="終了(_X)">
         <MenuItem.Icon><Image Source=".\icons\exit.png"/></MenuItem.Icon>
       </MenuItem>
     </MenuItem>
     <MenuItem Header="編集(_E)">
       <!--ApplicationCommands.Undo → フォーカスのあるコントロール(RichTextBox)の既定の動作を実行-->
       <MenuItem Header="元に戻す(_U)" Command="ApplicationCommands.Undo">
         <MenuItem.Icon><Image Source=".\icons\undo.png"/></MenuItem.Icon>
       </MenuItem>
       <!--ApplicationCommands.Redo → フォーカスのあるコントロール(RichTextBox)の既定の動作を実行-->
       <MenuItem Header="やり直し(_R)" Command="ApplicationCommands.Redo">
         <MenuItem.Icon><Image Source=".\icons\redo.png"/></MenuItem.Icon>
       </MenuItem>
       <Separator/>
       <!--ApplicationCommands.Cut → フォーカスのあるコントロール(RichTextBox)の既定の動作を実行-->
       <MenuItem Header="切り取り(_T)" Command="ApplicationCommands.Cut">
         <MenuItem.Icon><Image Source=".\icons\cut.png"/></MenuItem.Icon>
       </MenuItem>
       <!--ApplicationCommands.Copy → フォーカスのあるコントロール(RichTextBox)の既定の動作を実行-->
       <MenuItem Header="コピー(_C)" Command="ApplicationCommands.Copy">
         <MenuItem.Icon><Image Source=".\icons\copy.png"/></MenuItem.Icon>
       </MenuItem>
       <!--ApplicationCommands.Paste → フォーカスのあるコントロール(RichTextBox)の既定の動作を実行-->
       <MenuItem Header="貼り付け(_P)" Command="ApplicationCommands.Paste">
         <MenuItem.Icon><Image Source=".\icons\paste.png"/></MenuItem.Icon>
       </MenuItem>
       <!--ApplicationCommands.Delete → フォーカスのあるコントロール(RichTextBox)の既定の動作を実行-->
       <MenuItem Header="削除(_D)" Command="ApplicationCommands.Delete">
         <MenuItem.Icon><Image Source=".\icons\delete.png"/></MenuItem.Icon>
       </MenuItem>
       <MenuItem Header="配置(_A)">
         <!--EditingCommands.AlignLeft → フォーカスのあるコントロール(RichTextBox)の既定の動作を実行-->
         <MenuItem Header="左揃え" Command="EditingCommands.AlignLeft">
           <MenuItem.Icon><Image Source=".\icons\text_align_left.png"/></MenuItem.Icon>
         </MenuItem>
         <!--EditingCommands.AlignCenter → フォーカスのあるコントロール(RichTextBox)の既定の動作を実行-->
         <MenuItem Header="中央揃え" Command="EditingCommands.AlignCenter">
           <MenuItem.Icon><Image Source=".\icons\text_align_center.png"/></MenuItem.Icon>
         </MenuItem>
         <!--EditingCommands.AlignRight → フォーカスのあるコントロール(RichTextBox)の既定の動作を実行-->
         <MenuItem Header="右揃え" Command="EditingCommands.AlignRight">
           <MenuItem.Icon><Image Source=".\icons\text_align_right.png"/></MenuItem.Icon>
         </MenuItem>
         <!--EditingCommands.AlignJustify → フォーカスのあるコントロール(RichTextBox)の既定の動作を実行-->
         <MenuItem Header="両端揃え" Command="EditingCommands.AlignJustify">
           <MenuItem.Icon><Image Source=".\icons\text_align_justify.png"/></MenuItem.Icon>
         </MenuItem>
       </MenuItem>
       <MenuItem Header="スタイル(_S)">
         <!--EditingCommands.ToggleBold → フォーカスのあるコントロール(RichTextBox)の既定の動作を実行-->
         <MenuItem Header="太字" Command="EditingCommands.ToggleBold">
           <MenuItem.Icon><Image Source=".\icons\text_bold.png"/></MenuItem.Icon>
         </MenuItem>
         <!--EditingCommands.ToggleItalic → フォーカスのあるコントロール(RichTextBox)の既定の動作を実行-->
         <MenuItem Header="斜体" Command="EditingCommands.ToggleItalic">
           <MenuItem.Icon><Image Source=".\icons\text_italic.png"/></MenuItem.Icon>
         </MenuItem>
         <!--EditingCommands.ToggleUnderline → フォーカスのあるコントロール(RichTextBox)の既定の動作を実行-->
         <MenuItem Header="下線" Command="EditingCommands.ToggleUnderline">
           <MenuItem.Icon><Image Source=".\icons\text_underline.png"/></MenuItem.Icon>
         </MenuItem>
         <!--EditingCommands.ToggleBullets → フォーカスのあるコントロール(RichTextBox)の既定の動作を実行-->
         <MenuItem Header="箇条書き" Command="EditingCommands.ToggleBullets">
           <MenuItem.Icon><Image Source=".\icons\text_list_bullets.png"/></MenuItem.Icon>
         </MenuItem>
         <!--EditingCommands.ToggleNumbering → フォーカスのあるコントロール(RichTextBox)の既定の動作を実行-->
         <MenuItem Header="段落番号" Command="EditingCommands.ToggleNumbering">
           <MenuItem.Icon><Image Source=".\icons\text_list_numbers.png"/></MenuItem.Icon>
         </MenuItem>
         <!--EditingCommands.IncreaseIndentation → フォーカスのあるコントロール(RichTextBox)の既定の動作を実行-->
         <MenuItem Header="インデントを増やす" Command="EditingCommands.IncreaseIndentation">
           <MenuItem.Icon><Image Source=".\icons\text_indent.png"/></MenuItem.Icon>
         </MenuItem>
         <!--EditingCommands.DecreaseIndentation → フォーカスのあるコントロール(RichTextBox)の既定の動作を実行-->
         <MenuItem Header="インデントを減らす" Command="EditingCommands.DecreaseIndentation">
           <MenuItem.Icon><Image Source=".\icons\text_indent_remove.png"/></MenuItem.Icon>
         </MenuItem>
       </MenuItem>
       <MenuItem Header="テキスト(_T)">
         <!--EditingCommands.IncreaseFontSize → フォーカスのあるコントロール(RichTextBox)の既定の動作を実行-->
         <MenuItem Header="フォントの拡大" Command="EditingCommands.IncreaseFontSize"/>
         <!--EditingCommands.DecreaseFontSize → フォーカスのあるコントロール(RichTextBox)の既定の動作を実行-->
         <MenuItem Header="フォントの縮小" Command="EditingCommands.DecreaseFontSize"/>
       </MenuItem>
     </MenuItem>
     <MenuItem Header="ヘルプ(_H)">
       <!--RoutedCommandをコードビハインドから自作しカスタム動作(実行可否、イベント処理)を実装する-->
       <MenuItem Header="バージョン情報(_A)" Name="About">
         <MenuItem.Icon><Image Source=".\icons\about.png"/></MenuItem.Icon>
       </MenuItem>
     </MenuItem>
   </Menu>
   <ToolBarTray DockPanel.Dock="Top">
     <ToolBar Header="編集:">
       <Button ToolTip="元に戻す" Command="ApplicationCommands.Undo">
         <Image Source=".\icons\undo.png" Stretch="Fill"/></Button>
       <Button ToolTip="やり直し" Command="ApplicationCommands.Redo">
         <Image Source=".\icons\redo.png" Stretch="Fill"/></Button>
       <Button ToolTip="切り取り" Command="ApplicationCommands.Cut">
         <Image Source=".\icons\cut.png" Stretch="Fill"/></Button>
       <Button ToolTip="コピー" Command="ApplicationCommands.Copy">
         <Image Source=".\icons\copy.png" Stretch="Fill"/></Button>
       <Button ToolTip="貼り付け" Command="ApplicationCommands.Paste">
         <Image Source=".\icons\paste.png" Stretch="Fill"/></Button>
       <Button ToolTip="削除" Command="ApplicationCommands.Delete">
         <Image Source=".\icons\delete.png" Stretch="Fill"/>
       </Button>
     </ToolBar>
     <ToolBar Header="配置:">
       <Button ToolTip="左揃え" Command="EditingCommands.AlignLeft">
         <Image Source=".\icons\text_align_left.png" Stretch="Fill"/></Button>
       <Button ToolTip="中央揃え" Command="EditingCommands.AlignCenter">
         <Image Source=".\icons\text_align_center.png" Stretch="Fill"/></Button>
       <Button ToolTip="右揃え" Command="EditingCommands.AlignRight">
         <Image Source=".\icons\text_align_right.png" Stretch="Fill"/></Button>
       <Button ToolTip="両端揃え" Command="EditingCommands.AlignJustify">
         <Image Source=".\icons\text_align_justify.png" Stretch="Fill"/></Button>
     </ToolBar>
     <ToolBar Header="スタイル:">
       <Button ToolTip="太字" Command="EditingCommands.ToggleBold">
         <Image Source=".\icons\text_bold.png" Stretch="Fill"/></Button>
       <Button ToolTip="斜体" Command="EditingCommands.ToggleItalic">
         <Image Source=".\icons\text_italic.png" Stretch="Fill"/></Button>
       <Button ToolTip="下線" Command="EditingCommands.ToggleUnderline">
         <Image Source=".\icons\text_underline.png" Stretch="Fill"/></Button>
       <Button ToolTip="箇条書き" Command="EditingCommands.ToggleBullets">
         <Image Source=".\icons\text_list_bullets.png" Stretch="Fill"/></Button>
       <Button ToolTip="段落番号" Command="EditingCommands.ToggleNumbering">
         <Image Source=".\icons\text_list_numbers.png" Stretch="fill"/></Button>
       <Button ToolTip="インデントを増やす" Command="EditingCommands.IncreaseIndentation">
         <Image Source=".\icons\text_indent.png" Stretch="Fill"/></Button>
       <Button ToolTip="インデントを減らす" Command="EditingCommands.DecreaseIndentation">
         <Image Source=".\icons\text_indent_remove.png" Stretch="Fill"/></Button>
     </ToolBar>
   </ToolBarTray>
   <RichTextBox DockPanel.Dock="Top" Width="Auto" Height="100"
     IsDocumentEnabled="True" AcceptsTab="True" FontSize="24"/>
   <RichTextBox DockPanel.Dock="Top" Width="Auto" Height="100"
     IsDocumentEnabled="True" AcceptsTab="True" FontSize="24"/>
 </DockPanel>

-コード ビハインド
 /// <summary>Window1.xaml の相互作用ロジック</summary>
 public partial class Window1 : Window {
   public Window1() {
     InitializeComponent();
 
     // UIElementにRoutedCommandをバインドし、メニューに関連付ける。
     InitRoutedCommands_about();
   }
 
   // AboutCommand(カスタムのRoutedCommand)
   public static readonly RoutedCommand AboutCommand = new RoutedCommand();
 
   private void InitRoutedCommands_about() {
 
     // CommandBindingの生成
     CommandBinding binding = 
       new CommandBinding(AboutCommand, AboutCommand_Executed, AboutCommand_CanExecute);
 
     // UIElementにRoutedCommandをバインド
     this.CommandBindings.Add(binding);
 
     // メニューに関連付け
     About.Command = AboutCommand;
   }
 
   // 【情報メニュー+コマンド】UIElementにRoutedCommandをバインド:カスタム動作(実行可否)
   private void AboutCommand_CanExecute(object sender, CanExecuteRoutedEventArgs e) { 
     e.CanExecute = true;
   }
   // 【情報メニュー+コマンド】UIElementにRoutedCommandをバインド:カスタム動作(実行可否)
   private void AboutCommand_Executed(object sender, ExecutedRoutedEventArgs e) {
     // 情報表示処理
   }
 
   // 【保存メニュー+コマンド】UIElementにRoutedCommandをバインド:カスタム動作(実行可否)
   private void SaveCommand_CanExecute(object sender, CanExecuteRoutedEventArgs e) { 
     e.CanExecute = true;
   }
   // 【保存メニュー+コマンド】UIElementにRoutedCommandをバインド:カスタム動作(イベント処理)
   private void SaveCommand_Executed(object sender, ExecutedRoutedEventArgs e) {
     // 保存処理
   }
 
   // 【終了メニュー+コマンド】UIElementにRoutedCommandをバインド:カスタム動作(実行可否)
   private void CloseCommand_CanExecute(object sender, CanExecuteRoutedEventArgs e) { 
     e.CanExecute = true;
   }
   // 【終了メニュー+コマンド】UIElementにRoutedCommandをバインド:カスタム動作(イベント処理)
   private void CloseCommand_Executed(object sender, ExecutedRoutedEventArgs e) { 
     this.Close();
   }
 
   // 【終了メニュー】メニューのクリックイベントのみの実装で済ます場合。
   private void Exit_Click(object sender, RoutedEventArgs e) { 
     this.Close();
   }
 }


***説明 [#pd837bfb]
-メニュー・タスクバーと「コマンド」の関連付け
--MenuItem
---MenuItem(MenuItem クラス)は入れ子が可能であり、
---MenuItemのアクセスキーは、MenuItemクラスのHeader属性に指定する文字列中に~
「英数字」と設定することで(英数字の先頭文字をアクセスキーとして)容易に設定可能
---また、MenuItemからはCommand属性を指定して指定の「Command」を発生させることができる。

--ToolBarTray
---ToolBarTray には、を格納でき、ToolBarにはButtonを格納できる。
---Buttonからは指定の「Command」を発生させることができる。
---ToolBarTray内のToolBarは、実行時にD&Dにて配置を変更できる。

--Command
---これらのコントロールから発生させた「Command」は、フォーカスのあるコントロールに受信されるが、
---CommandTarget="{Binding ElementName=要素名}"という記述により、対象のコントロールを明示することもできる。
---対象のコントロールは、各種RoutedCommand クラスのCanExecute、Executeメソッドが~
発生させるイベントを処理するイベント ハンドラを実装している必要がある。

-標準コマンド

--標準コマンド(ApplicationCommands, EditingCommands, etc. )に対応した処理を実装しているコントロールには、~
---「コマンド」に対応する処理のUOCは不要であり、既定の処理が実行される。
---また、「コマンド」には、既定のショートカットも割り当てられている。

--コントロールの実装する標準コマンド(上記サンプルでは、ApplicationCommands.Save・Close)の処理をカスタマイズしたい場合、

---「コマンド」に対応したイベント ハンドラのUOCをUIElement(上記サンプルでは、Window)に定義・実装する必要がある。

---標準コマンドのカスタム処理の定義・実装には、標準コマンド(ApplicationCommands)をUIElementのCommandBindingsプロパティに追加し、~
ApplicationCommands.CanExecute、Executeが発生させるカスタム イベントを処理するイベント ハンドラのUOCをUIElement上に実装する必要がある。

---また、上記の方式は、カスタム コマンド(RoutedCommand)に対応したイベント ハンドラのUOCをUIElementに定義・実装する場合にも利用できる。

--その他にも、以下の標準コマンドがSystem.Windows.Input名前空間に用意されている。
---ComponentCommands
---MediaCommands
---NavigationCommands

***参考 [#v7fadce9]
-MSDN
--Windows Presentation Foundation > コントロール > メニューの概要~
http://msdn.microsoft.com/ja-jp/library/ms747430.aspx

--.NET Frameworkクラス ライブラリ

---System.Windows.Controls.MenuItemクラス~
http://msdn.microsoft.com/ja-jp/library/system.windows.controls.menuitem.aspx
---System.Windows.Controls.ToolBarTrayクラス~
http://msdn.microsoft.com/ja-jp/library/system.windows.controls.toolbartray.aspx
---System.Windows.Controls.ToolBarクラス~
http://msdn.microsoft.com/ja-jp/library/system.windows.controls.toolbar.aspx
---System.Windows.Input.RoutedCommandクラス~
http://msdn.microsoft.com/ja-jp/library/system.windows.input.routedcommand.aspx

---System.Windows.Input.ApplicationCommandsクラス~
http://msdn.microsoft.com/ja-jp/library/system.windows.input.applicationcommands.aspx
---System.Windows.Documents.EditingCommandsクラス~
http://msdn.microsoft.com/ja-jp/library/system.windows.documents.editingcommands.aspx


**ツールチップ [#bd8125d8]
-WPFでは、「ツールチップ」を任意のUIコントロールに設定可能である。
-これにはFrameworkElement、FrameworkContentElementにToolTip プロパティが実装されているためである。

***実装 [#p041613d]
-画面
#ref(Tooltip.png,left,nowrap,ツールチップ)

-XAML
--UserControl
 <UserControl x:Class="WpfApplication1.UserControl1"
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   Width="250" Height="120">
   <StackPanel>
     <TextBlock Margin="4,4,4,4" Text="タイトル"
       TextWrapping="Wrap" FontWeight="Bold" FontSize="14"/>
     <Path Width="Auto" Height="1" 
       Fill="Black" Stretch="Fill" 
       Stroke="Black" Data="M20,45 L250,45" 
       Margin="4,4,4,4"/>
     <TextBlock Margin="4,4,4,4" Text="説明文" 
       TextWrapping="Wrap"/>
   </StackPanel>
 </UserControl>

--Window
 <Window x:Class="WpfApplication1.Window1"
   ・・・
     xmlns:my="clr-namespace:WpfApplication1"
   ・・・>
 
   ・・・
 
 <RichTextBox DockPanel.Dock="Top" Width="Auto" Height="100" 
              IsDocumentEnabled="True" AcceptsTab="True" FontSize="24">
   <RichTextBox.ToolTip>
     <ToolTip>
       <my:UserControl1/>
     </ToolTip>
   </RichTextBox.ToolTip>
 </RichTextBox>

***説明 [#lbcc9016]
このToolTipプロパティには、ToolTip属性に直接文字列で説明文を記述することも可能であるが、~
「プロパティ要素構文」を使用して、説明文などの文字列だけではなく、(imageなどの)任意のUI要素も設定可能である。~
例えば、以下は、ユーザ コントロールを使用してToolTipを表示した例である。

***参考 [#j60feaeb]
-MSDN > .NET Frameworkクラス ライブラリ
--System.Windows.FrameworkElement.ToolTipプロパティ~
http://msdn.microsoft.com/ja-jp/library/system.windows.documents.editingcommands.aspx
--System.Windows.FrameworkContentElement.ToolTipプロパティ~
http://msdn.microsoft.com/ja-jp/library/system.windows.frameworkcontentelement.tooltip.aspx

**IME制御 [#e48a4e9d]
-WPF / Silverlightでは、InputMethod クラスを利用することでIME制御が可能である(XAMLから直接指定することも可能)。

-ただし、
--IME2003以外では、IMEのオン・オフの切り替え(ひらがな ⇔ 直接入力)はできるが、
--入力モードの切り替え(カタカナ ⇔ 全角英字など)はできないので注意が必要 。

-切り替え方法
--IMEオン・オフ
---InputMethod.SetIsInputMethodEnabledメソッド
---InputMethod.Current.ImeStateプロパティ
--入力モード
---InputMethod.SetPreferredImeConversionModeメソッド
---InputMethod.Current.ImeConversionModeプロパティ

***実装 [#h5db94a5]
以下は、IME制御のサンプルである。

-画面
#ref(IME-Control.png,left,nowrap,IME制御)

-XAML~
イベント ハンドラでIME制御する方法と、XAMLでIME制御する方法がある。

--イベント ハンドラでIME制御
 <StackPanel Orientation="Vertical">
   <StackPanel Orientation="Horizontal">
     <TextBlock Height="23" Width="80" Text="制御なし:"/>
     <TextBox Name="textBox0" Height="23" Width="120"/>
   </StackPanel>
   <StackPanel Orientation="Horizontal">
     <TextBlock Height="23" Text="以下、イベントで制御"/>
   </StackPanel>
   <StackPanel Orientation="Horizontal">
     <TextBlock Height="23" Width="80" Text="OFF:"/>
     <TextBox Name="textBox1" Height="23" Width="120"
       GotFocus="textBox1_GotFocus" LostFocus="textBox1_LostFocus"/>
   </StackPanel>
   <StackPanel Orientation="Horizontal">
     <TextBlock Height="23" Width="80" Text="ON:"/>
     <TextBox Name="textBox2" Height="23" Width="120"
       GotFocus="textBox2_GotFocus" LostFocus="textBox2_LostFocus"/>
   </StackPanel>
   <StackPanel Orientation="Horizontal">
     <TextBlock Height="23" Width="80" Text="全角片仮名:"/>
     <TextBox Name="textBox3" Height="23" Width="120"
       GotFocus="textBox3_GotFocus" LostFocus="textBox3_LostFocus"/>
   </StackPanel>

--XAMLでIME制御
   <StackPanel Orientation="Horizontal">
     <TextBlock Height="23" Text="以下、XAMLで制御"/>
   </StackPanel>
   <StackPanel Orientation="Horizontal">
     <TextBlock Height="23" Width="80" Text="OFF:"/>
     <TextBox Name="textBox4" Height="23" Width="120"
       InputMethod.PreferredImeState="Off"/>
   </StackPanel>
   <StackPanel Orientation="Horizontal">
     <TextBlock Height="23" Width="80" Text="ON:"/>
     <TextBox Name="textBox5" Height="23" Width="120"
       InputMethod.PreferredImeState="On"/>
   </StackPanel>
   <StackPanel Orientation="Horizontal">
     <TextBlock Height="23" Width="80" Text="半角片仮名:"/>
     <TextBox Name="textBox6" Height="23" Width="120"
       InputMethod.PreferredImeState="On" InputMethod.PreferredImeConversionMode="Native,Fixed,Katakana"/>
   </StackPanel>
 </StackPanel>

-コード ビハインド~
下記はイベント ハンドラによるIME制御である。
 /// <summary>Window1.xaml の相互作用ロジック</summary>
 public partial class Window1 : Window {
   public Window1() {
     InitializeComponent();
   }
 
   InputMethodState ims = InputMethodState.DoNotCare;
   ImeConversionModeValues imc = ImeConversionModeValues.DoNotCare;
 
   private void textBox1_GotFocus(object sender, RoutedEventArgs e) {
     ims = InputMethod.Current.ImeState;
     InputMethod.Current.ImeState = InputMethodState.Off;
   }
   private void textBox1_LostFocus(object sender, RoutedEventArgs e) {
     InputMethod.Current.ImeState = ims;
   }
 
   private void textBox2_GotFocus(object sender, RoutedEventArgs e) {
     ims = InputMethod.Current.ImeState;
      InputMethod.Current.ImeState = InputMethodState.On;
   }
   private void textBox2_LostFocus(object sender, RoutedEventArgs e) {
     InputMethod.Current.ImeState = ims;
   }
 
   private void textBox3_GotFocus(object sender, RoutedEventArgs e) {
     ims = InputMethod.Current.ImeState;
     imc = InputMethod.Current.ImeConversionMode;
 
     InputMethod.Current.ImeState = InputMethodState.On;
     InputMethod.Current.ImeConversionMode = ImeConversionModeValues.Native
       | ImeConversionModeValues.FullShape | ImeConversionModeValues.Katakana;
   }
   private void textBox3_LostFocus(object sender, RoutedEventArgs e) {
     InputMethod.Current.ImeState = ims;
     InputMethod.Current.ImeConversionMode = imc;
   }
 }

***説明 [#of372628]
イベント ハンドラでのIME制御の動作は、~
以下の点が、XAMLによるIME制御の場合と異なる。

-GotFocus、LostFocusイベントを扱っており、~
GotFocusイベントで現状のIME設定を保存し、~
LostFocusイベントでIME設定を復元している。

-このため、入力時のIME設定変更はLostFocusイベントで無効になる。

***参考 [#fe6aa6ad]
-MSDN > .NET Frameworkクラス ライブラリ
--System.Windows.Input.InputMethodクラス~
http://msdn.microsoft.com/ja-jp/library/system.windows.input.inputmethod.aspx
--System.Windows.Input.InputMethodクラス~
http://msdn.microsoft.com/ja-jp/library/system.windows.input.inputmethod(VS.95).aspx

-Microsoft Connect|WinXP&IME2003環境で、WPFのTextBoxに対するIME制御(カタカナ指定)ができない~
http://connect.microsoft.com/VisualStudioJapan/feedback/details/375651/winxp-ime2003-wpf-textbox-ime

*デザイナ向け機能 [#jb851708]
デザイナ向けの技術要素について説明する。

**様々なシェイプ [#yc5dd22e]
-[[「クラス階層」のVisualクラス>WPFのアーキテクチャ#s4219d62]]で説明したように、~
WPF / Silverlightでは、Shape クラスから派生する様々なベクタ グラフィックスを記述できる。

-Shapeクラスから派生するベクタ グラフィックス描画クラスには、次のものがある。
--Rectangle クラス~
四角形を描画

--Ellipse クラス~
楕円を描画

--Line クラス~
直線を描画

--Polyline クラス~
一連の直線を描画

--Path クラス~
一連の直線と曲線を描画

***実装 [#q14db6d3]
-ただし、Visual StudioではPath 要素の編集が困難である。~
このためExpression Blendのデザイナでは、[ペン]や[鉛筆]など、Path 要素の編集用ツールを使用すると良い。~
以下は、Expression Blendデザイナの[ペン]や[鉛筆]を使用して記述したPath 要素の描画である。

--画面
#ref(Path.png,left,nowrap,様々なシェイプ(Path),60%)

--XAML
 <Grid>
   <Path Fill="White" Stretch="Fill" Stroke="Black" StrokeThickness="5"
     Data="M208,68 C182.37169,68 155.97712,69 131,69 ・・・"/>
   <Path Fill="White" Stretch="Fill" Stroke="Black" StrokeThickness="5" Margin="50"
     Data="M88,132 C88,132 87.5,250.5 120.5,234.5 ・・・"/>
 </Grid>

-さらに、VSやExpression Blendを用い、Ellipse・TextBlockなどの描画コンテンツを作成し、~
これをExpression Blendで、これらをPath に変換するといった機能も用意されている。

--画面
#ref(EllipseAndTextBlock.png,left,nowrap,様々なシェイプ(Ellipse・TextBlock),60%)

--XAML
 <Grid>
   <Viewbox Height="400" Width="400">
     <Grid>
       <Ellipse Stroke="Black" StrokeThickness="5"
         Height="400" Width="400"/>
       <TextBlock Text="WPF" FontSize="150"
         HorizontalAlignment="Center" VerticalAlignment="Center"/>
     </Grid>
   </Viewbox>
 </Grid>

-この変換を行うには、Expression Blend の[オブジェクトとタイムライン]でEllipse・TextBlockを選択した状態で、~
メニューの[オブジェクト] → [パス] → [複合パスの作成]を選択する。以下は、上記のEllipse・TextBlockをPath に変換したXAMLである。

--XAML
 <Grid>
   <Path Data="M397.5,200 C397.5,309.07624 309.07624,397.5 200,397.5 C90.923762,397.5 2.5,309.07624 2.5,200 C2.5,90.923762 90.923762,2.5 200,2.5 C309.07624,2.5 397.5,90.923762 397.5,200 z M59.0835,149.3165 L71.974126,149.3165 L87.794437,223.73042 L107.13037,149.3165 L120.021,149.3165 L139.35694,223.73042 L155.17725,149.3165 L168.06787,149.3165 L145.80225,250.6835 L134.0835,250.6835 L113.57569,169.23834 L93.067874,250.6835 L81.349124,250.6835 z M192.08984,160.44929 L192.08984,199.1211 L222.55859,199.1211 C228.02734,199.1211 232.32422,197.5586 235.44922,194.4336 C238.96484,190.91799 240.72266,186.23049 240.72266,180.37113 C240.72266,173.73052 239.16016,168.84771 236.03516,165.72272 C232.51953,162.2071 228.02734,160.44929 222.55859,160.44929 z M178.61329,149.3165 L225.48828,149.3165 C234.08203,149.31651 241.11328,152.05088 246.58203,157.51961 C252.05078,162.98835 254.78515,170.60552 254.78515,180.37113 C254.78515,190.13674 252.24609,197.5586 247.16797,202.63671 C242.08984,207.71483 234.86328,210.25389 225.48828,210.25389 L192.08984,210.25389 L192.08984,249.51163 L178.61329,249.51163 z M273.5337,149.3165 L340.9165,149.3165 L340.9165,160.44929 L287.01027,160.44929 L287.01027,193.26173 L329.19775,193.26173 L329.19775,204.39452 L287.01027,204.39452 L287.01027,249.51163 L273.5337,249.51163 z" Stretch="Fill" Stroke="Black" StrokeThickness="5"/>
 </Grid>

***参考 [#i3eb775f]
-MSDN
--System.Windows.Shapes.Shapeクラス
---.NET Frameworkクラス ライブラリ~
http://msdn.microsoft.com/ja-jp/library/system.windows.shapes.shape.aspx
---Silverlightの.NET Frameworkクラス ライブラリ ~
http://msdn.microsoft.com/ja-jp/library/system.windows.shapes.shape(VS.95).aspx
---MSDNマガジン > 発行物 > 基礎:ベクタ グラフィックスとWPFのShapeクラス~
http://msdn.microsoft.com/ja-jp/magazine/cc337899.aspx

--System.Windows.Shapes.Rectangleクラス
---.NET Frameworkクラス ライブラリ~
http://msdn.microsoft.com/ja-jp/library/system.windows.shapes.rectangle.aspx
---Silverlightの.NET Frameworkクラス ライブラリ ~
http://msdn.microsoft.com/ja-jp/library/system.windows.shapes.rectangle(VS.95).aspx

--System.Windows.Shapes.Ellipseクラス
---.NET Frameworkクラス ライブラリ~
http://msdn.microsoft.com/ja-jp/library/system.windows.shapes.ellipse.aspx
---Silverlightの.NET Frameworkクラス ライブラリ ~
http://msdn.microsoft.com/ja-jp/library/system.windows.shapes.ellipse(VS.95).aspx

--System.Windows.Shapes.Lineクラス
---.NET Frameworkクラス ライブラリ~
http://msdn.microsoft.com/ja-jp/library/system.windows.shapes.line.aspx
---Silverlightの.NET Frameworkクラス ライブラリ ~
http://msdn.microsoft.com/ja-jp/library/system.windows.shapes.line(VS.95).aspx

--System.Windows.Shapes.Polylineクラス
---.NET Frameworkクラス ライブラリ~
http://msdn.microsoft.com/ja-jp/library/system.windows.shapes.polyline.aspx
---Silverlightの.NET Frameworkクラス ライブラリ ~
http://msdn.microsoft.com/ja-jp/library/system.windows.shapes.polyline(VS.95).aspx

--System.Windows.Shapes.Pathクラス
---.NET Frameworkクラス ライブラリ~
http://msdn.microsoft.com/ja-jp/library/system.windows.shapes.path.aspx
---Silverlightの.NET Frameworkクラス ライブラリ ~
http://msdn.microsoft.com/ja-jp/library/system.windows.shapes.path(VS.95).aspx

**グラデーション [#hda741d1]
WPF / Silverlightでは、様々なグラデーションをデザイン可能。

***実装 [#fe777167]
-簡単なグラデーション~
以下の簡素なグラデーションであれば、XAMLで直接記述することも可能。

--画面
#ref(EasyGradation.png,left,nowrap,簡単なグラデーション)

--XAML
 <Window.Background>
   <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
     <GradientStop Color="Black" Offset="0"/>
     <GradientStop Color="White" Offset="1"/>
   </LinearGradientBrush>
 </Window.Background>

-複雑なグラデーション~
しかし、以下の複雑なグラデーションであれば、~
Expression Blendのデザイナを使用した方が、容易にグラデーションをデザインできる。

--画面
#ref(ComplexGradation.png,left,nowrap,複雑なグラデーション)

--XAML
 <Window.Background>
   <RadialGradientBrush GradientOrigin="0.3,0.3">
     <GradientStop Color="Aqua" Offset="0.1"/>
     <GradientStop Color="Black" Offset="0.2"/>
     <GradientStop Color="Aqua" Offset="0.3"/>
     <GradientStop Color="Black" Offset="0.4"/>
     <GradientStop Color="Aqua" Offset="0.5"/>
     <GradientStop Color="Black" Offset="0.6"/>
     <GradientStop Color="Aqua" Offset="0.7"/>
     <GradientStop Color="Black" Offset="0.8"/>
     <GradientStop Color="Aqua" Offset="0.9"/>
   </RadialGradientBrush>
 </Window.Background>

**トランスフォーム処理 [#v0a7e63e]
-WPFで2D平面での変換を行う「トランスフォーム処理」を使用して以下の効果を追加できる。
--「回転、拡大縮小、傾斜、平行移動」
--「アニメーションなど一時効果」

-「トランスフォーム処理」に使用できるクラスには、~
System.Windows.Media名前空間のTransform クラスから派生する、下記クラスがある。
--MatrixTransform
--RotateTransform
--ScaleTransform
--SkewTransform
--TranslateTransform
--TransformGroup

-なお、TransformGroupを使用すれば、~
複数のTransformクラスを組み合わせて適用することができる。

-以下、下記の図形に対する、上記2つの「トランスフォーム処理」の例。

--画面
#ref(PreTransform.png,left,nowrap,トランスフォーム前)

--XAML
 <Grid>
   <Border Height="100" Width="100" BorderBrush="Black" BorderThickness="1" >
     <Rectangle Height="100" Width="100" Fill="Blue"/>
   </Border>
 </Grid>

***回転、拡大縮小、傾斜、平行移動 [#eea9fcaa]
-FrameworkElement.LayoutTransformプロパティに設定されたTransformクラスを使用し、~
レイアウト時に「トランスフォーム処理」を実行する。
--このため、「トランスフォーム処理」後もUI要素がレイアウト時の描画領域内に収まる。
--このような特徴から、この「トランスフォーム処理」は、~
表示を垂直から水平に切り替えたり、ズームしたりするなどの用途で利用可能である。

-以下は、LayoutTransformプロパティにRotateTransformクラスを指定してUI要素を回転させた例である。

--画面
#ref(AfterLayoutTransform.png,left,nowrap,回転、拡大縮小、傾斜、平行移動)

--XAML
 <Grid>
   <Border Height="100" Width="100" BorderBrush="Black" BorderThickness="1" >
     <Rectangle Height="100" Width="100" Fill="Blue">
       <Rectangle.LayoutTransform>
         <RotateTransform CenterX="50" CenterY="50" Angle="45"/>
       </Rectangle.LayoutTransform>
     </Rectangle>
   </Border>
 </Grid>

***アニメーションなど一時効果の追加 [#g7192384]
-UIElement.RenderTransformプロパティに設定されたTransformクラスを使用し、~
レイアウト後に「トランスフォーム処理」しレンダリングする。
--このため、場合によってはUI要素がレイアウトの描画領域の外にでてしまう場合がある。
--このような特徴から、この「トランスフォーム処理」は、~
「アニメーション」(後述)と組み合わせるなどしてUI要素に注目を集めるなどの用途で利用可能である。

-以下は、RenderTransformプロパティにRotateTransformクラスを指定してUI要素を回転させた例である。

--画面
#ref(AfterRenderTransform.png,left,nowrap,アニメーションなど一時効果の追加)

--XAML
 <Grid>
   <Border Height="100" Width="100" BorderBrush="Black" BorderThickness="1" >
     <Rectangle Height="100" Width="100" Fill="Blue">
       <Rectangle.RenderTransform>
         <RotateTransform CenterX="50" CenterY="50" Angle="45"/>
       </Rectangle.RenderTransform>
     </Rectangle>
   </Border>
 </Grid>

※ なお、こちらの「トランスフォーム処理」は「Silverlight」でもサポートされる。

***参考 [#z347d280]
-MSDN
--System.Windows.Media.Transformクラス
---.NET Frameworkクラス ライブラリ~
http://msdn.microsoft.com/ja-jp/library/system.windows.media.transform.aspx
---Silverlightの.NET Frameworkクラス ライブラリ~
http://msdn.microsoft.com/ja-jp/library/system.windows.media.transform(VS.95).aspx

**アニメーション [#x6c21b91]

***実装 [#idce5d4d]

***説明 [#m9ad9bf8]

***参考 [#df9654b1]

*MVVMデザイン パターン [#i380f3a3]

**概要 [#w9210446]
MVVM(Model - View - View Model)モデルとは、~
前述の「データ バインディング」の仕組みを活用したデザイン パターンであり、~
従来の3層デザイン パターンの「モデル オブジェクト」、「ビュー オブジェクト」に加えて、~
「バインディング ソース」である「ビュー・モデル オブジェクト」を新設するデザイン パターンである。

**メリット [#z0b52812]
このデザイン パターンのメリットは、~
「モデル オブジェクト」、「ビュー オブジェクト」間の結合部を、~
「データ バインディング」による「ビュー・モデル オブジェクト」に限定し、疎結合を実現できる点である。

**ガイドライン [#s86bd6d9]
なお、MVVMデザイン パターンのためのガイドライン には、以下のものがある。

+XAMLで実装できるものは、コードビハインドに実装しない。
+「ビュー・モデル オブジェクト」はDataContextとして「ビュー オブジェクト」に渡す。
+「ビュー・モデル オブジェクト」と「モデル オブジェクト」は、~
「データ バインディング」により結合されるため、「ビュー オブジェクト」には、一切アクセスしない。
+「ビュー・モデル オブジェクト」は、INotifyPropertyChangedインターフェイスを実装するべき。
+「ビュー・モデル オブジェクト」は、「モデル オブジェクト」をカプセル化することで、~
「ビュー オブジェクト」から、データ ストレージの複雑さを隠蔽する。

**参考 [#xb7f1d2d]
-MSDNマガジン > 発行物 > Model - View - ViewModelデザイン パターンによるWPFアプリケーション~
http://msdn.microsoft.com/ja-jp/magazine/dd419663.aspx

-Moving from Windows Applications to WPF - CodeProject~
http://www.codeproject.com/KB/WPF/WPF_with_MVVM.aspx?msg=3220512
#ref(MVVM.png,left,nowrap,Model - View - ViewModelデザイン パターン)

*バリデーション [#wff8a95a]
-WPFのバリデーション・フレームワークの使い方。

-以下をプロトタイプ開発したので参考にすることができる。

--SampleProgram/UISubsystem/WPF/Validation at master · OpenTouryoProject/SampleProgram~
https://github.com/OpenTouryoProject/SampleProgram/tree/master/UISubsystem/WPF/Validation

**単項目のバリデーション [#ob9f2bf4]
https://github.com/OpenTouryoProject/SampleProgram/tree/master/UISubsystem/WPF/Validation/InputField

**一覧のバリデーション [#ad58117e]
https://github.com/OpenTouryoProject/SampleProgram/tree/master/UISubsystem/WPF/Validation/DataGrid

**フォーカス制御 [#ue997b59]
フォーカス制御については、いろいろ試しているが~
問題が多いので使わない方向で考えた方が良さそう。

----
Tags: [[:.NET開発]], [[:UIサブシステム]], [[:WPF/Silverlight, XAML]]

トップ   編集 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS