「マイクロソフト系技術情報 Wiki」は、「Open棟梁Project」,「OSSコンソーシアム .NET開発基盤部会」によって運営されています。
目次 †
概要 †
XAMLの書き方(1)の続き。
ビルティング ブロック クラス †
WPF / Silverlightは、Windows Formsとは全く異なるUIサブシステムであるが、
類似のビルティング ブロック クラスが使用されているため、よく似たコードでプログラムを記述することができる。
Applicationオブジェクト †
WPF / SilverlightにはWindows フォームと同様に Applicationオブジェクトが存在する。
- 参考
- MSDN > .NET Frameworkクラス ライブラリ
画面の起動 †
- 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>
- 参考
- MSDN > .NET Frameworkクラス ライブラリ
イベント †
Applicationオブジェクトには様々なイベント処理を実装することができる。
- 開始イベント
WPF / Silverlightでの共通初期化処理を実装する場合、Application.Startup イベントを使用する。
- イベントの実装サンプル
以下、それぞれのイベントの実装サンプルである。
- 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
Application.Propertiesプロパティ †
- WPFではASP.NETなどのWebアプリケーションと同様のSession変数ライクな
Key - Valueストアとして、Application.Properties プロパティを利用可能である。
- 以下のサンプルで、任意の個所で(画面間を跨って)
Application.Propertiesプロパティが取得できることを確認できる。
- コード ビハインド
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();
}
- 参考
- MSDN > .NET Frameworkクラス ライブラリ
Window画面 †
- 参考
- MSDN > .NET Frameworkクラス ライブラリ
ウィンドウの起動 †
WPFではWindows Formsと同様にWindow 画面を、以下のように起動できる(「XBAP」を除く)。
プロパティ †
Windowには、以下のようなプロパティを設定できる。
- Title
Window.Title プロパティは、ウィンドウのタイトルを取得 / 設定する。
- WindowStartUpLocation?
Window. WindowStartUpLocation? プロパティは、
ウィンドウ起動時の表示位置を取得 / 設定する。
- ResizeMode?
Window. ResizeMode? プロパティは、ウィンドウの
サイズ変更モードを取得 / 設定する(ResizeMode? 列挙体)。
- WindowStyle?
Window. WindowStyle? プロパティは、
ウィンドウの境界線スタイルを取得 / 設定する。
- ShowInTaskbar?
Window. ShowInTaskbar? プロパティは、
タスクバーのアイコンの表示・非表示を取得 / 設定する。
- 参考
- MSDN > .NET Frameworkクラス ライブラリ > System.Windows.Window
ナビゲーション フレームワーク †
- WPF / Silverlightでは「ナビゲーション フレームワーク」によりASP.NETなどのWebアプリケーションと同様に、
WWWブラウザの単一ウィンドウ、複数ページから構成される画面を提供できる。
- この機能は、「ナビゲーション フレームワーク」のNavigationWindow? / Pageにより提供され、
ウィザードや、ハイパー テキスト ソリューションに有用である。
- なお、以下のような機能もサポートされている。
- WWWブラウザ型の単一ウィンドウ、複数ページから構成される画面を提供
- WWWブラウザ同様、画面遷移の履歴が残り[進む]・[戻る]操作に対応
- ハイパーリンクによる画面遷移、HTTPコンテンツの参照をサポート
- 以下、NavigationWindow? / Pageの使用方法を説明する。
NavigationWindow?画面を作成 †
- 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クラス ライブラリ
NavigationWindow?画面を起動 †
WPFでNavigationWindow?画面を起動する方法について説明する。
Page画面のロード (1) †
- WPFでNavigationWindow?画面から、Page 画面をロードする方法について説明する。
- なお、PageはFrameworkElement?からの派生クラスであって、
NavigationWindow?・Frame コントロールでのみホスト・ナビゲーションができる。
- 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画面をロードすることもできる。
- Frameコントロールからロード
Page内を複数のFrameに分割し、その中に複数のページをロードすることもできる。
- 参考
- MSDN > .NET Frameworkクラス ライブラリ
Page画面のロード (2) †
「XBAP」、「Silverlight」では、WindowNavigation? / Windowが使用出来ないため、以下の方法で、直接Page画面をロードする。
- 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画面の画面遷移 †
WPF / SilverlightにおけるPage画面の画面遷移方法について説明する。
- コードビハインドからの画面遷移
コード ビハインドからの画面遷移も可能である。
Page画面の進む・戻る操作への対応 †
- WPF / Silverlightでは、WWWブラウザ同様、進む・戻るボタンが常備されており、
進む・戻る操作に対応している(Webアプリケーションと同様に、戻った際は、前ページの入力の状態は保持されている)。
- コードビハインドからの進む・戻る操作
コードビハインドからは、次の処理で進む・戻る操作に対応できる。
- 履歴の管理
- 進む・戻る操作が行えるということは、画面遷移の履歴を保持しているということである。
- これを以下のコードで画面遷移の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画面の進む・戻る操作の注意点 †
- [新規画面遷移] → [戻る] → [進む]の一連の操作で、表示されるPageの再初期化が発生するので、
必要に応じてこれを考慮した実装とするか、[進む]・[戻る]操作を抑止する必要がある。
- 再初期化とは?
コンストラクタや、PageのLoadedイベントの処理の実行
- コンストラクタが実行されるのは、最初のPageのみである。
- LoadedイベントはすべてのPageで実行される。
- [進む]・[戻る]操作を抑止する。
先頭PageでPage.ShowsNavigationUIプロパティをfalseに設定にし、
以降のPageの[進む]・[戻る]ボタンを非表示にするか、前述の履歴消去で対応する。
- BackSpace?キーによる[戻る]を抑止
- [進む]・[戻る]ボタンを非表示にする場合もBackSpace?キーで戻ることができるので、必要に応じてBackSpace?キーを抑止する。
- また、UI要素にフォーカスの当たっていない状態では、BackSpace?キーを抑止することができないので、
Page.LoadedイベントなどでPage上の入力UI要素にフォーカスを当てるようにする。
- コード ビハインド
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;
}
}
その他 †
NavigationWindow? / Pageのその他のトピック
- UriMapper? クラスは「Silverlight」専用のコントロールになるが、
HyperlinkタグのNavigateUri?属性などで使用するPage.xamlへのパスを簡素化することができる。
- UriMapper?クラスは複数のUriMapping? クラスから構成され、
UriMapping?クラスのMappedUri?プロパティに実際のPage.xamlへのパス(のパターン)を指定、
Uriプロパティに簡素化したパス(のパターン)を指定する。
- 作成したUriMapper?オブジェクトをFrame.UriMapper?プロパティに
追加することで、Frame内で簡素化したパスを使用することができる。
- ChildWindow? コントロールは、「Silverlight」専用のコントロールであるが、
Page上に、子ウィンドウ(モーダル ダイアログ相当)を表示できる。
- 「Silverlight」アプリケーションのプロジェクトでは、
ChildWindow?のクラステンプレートが用意されており、
これを新規作成し、以下のコードでChildWindow?を呼び出すことができる。
- 注意事項
なお、NavigationWindow? / Pageの使用における注意点は、以下を参照のこと。
- ナビゲーション フレームワーク 参考情報
- MSDN > Silverlight > アプリケーション モデルとプログラミング モデル
- @IT > Insider.NET > 連載:Silverlight 3実践プログラミング
- CodeZine? > Silverlight 3徹底入門
- 参考
- MSDN > .NET Frameworkクラス ライブラリ
Win32ダイアログ †
- このため、WPF / Silverlightアプリケーションであるからと言って、
「外観や、操作方法の異なる標準ダイアログに慣れる必要がある」・・・といった問題は無い。
メッセージ ボックス †
下記のMessageBox?クラスの名前空間は、Windows FormsではなくWPFのものだが、
このMessageBox?クラスのクラス階層を確認するとWPFのアーキテクチャに基づいていないことが確認できる。
コモン ダイアログ ボックス †
- PrintDialog? クラス
- このクラスの名前空間は、Windows FormsではなくWPFのものだが、
クラス階層を確認するとWPFのアーキテクチャに基づいていないことが確認できる。
- Silverlightでは、Printdocument クラス
- 参考
- MSDN > .NET Frameworkクラス ライブラリ
- MSDN > Silverlightの.NET Frameworkクラス ライブラリ
- MSDN > Windows Presentation Foundation > ドキュメント
カスタム ダイアログ ボックス †
参考 †
- MSDN > Windows Presentation Foundation
- MSDN > Silverlight
入力支援 †
入力支援機能に関する技術要素について説明する。
メニュー・タスクバーとコマンド †
- メニュー・タスクバーと「コマンド」の関連付けも、宣言的プロパティにより実装・カスタマイズ可能。
- 例えば、以下のXAMLでメニュー・タスクバーと「コマンド」の概要を理解することができ、
また、メニュー・タスクバーと「コマンド」の関連付けが容易に実装可能であることが分かる。
実装 †
- コード ビハインド
/// <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();
}
}
説明 †
- メニュー・タスクバーと「コマンド」の関連付け
- 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?
参考 †
ツールチップ †
- WPFでは、「ツールチップ」を任意のUIコントロールに設定可能である。
- これにはFrameworkElement?、FrameworkContentElement?にToolTip? プロパティが実装されているためである。
実装 †
- 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>
説明 †
このToolTip?プロパティには、ToolTip?属性に直接文字列で説明文を記述することも可能であるが、
「プロパティ要素構文」を使用して、説明文などの文字列だけではなく、(imageなどの)任意のUI要素も設定可能である。
例えば、以下は、ユーザ コントロールを使用してToolTip?を表示した例である。
参考 †
- MSDN > .NET Frameworkクラス ライブラリ
IME制御 †
- WPF / Silverlightでは、InputMethod? クラスを利用することでIME制御が可能である(XAMLから直接指定することも可能)。
- ただし、
- IME2003以外では、IMEのオン・オフの切り替え(ひらがな ⇔ 直接入力)はできるが、
- 入力モードの切り替え(カタカナ ⇔ 全角英字など)はできないので注意が必要 。
- 切り替え方法
- IMEオン・オフ
- InputMethod?.SetIsInputMethodEnabled?メソッド
- InputMethod?.Current.ImeState?プロパティ
- 入力モード
- InputMethod?.SetPreferredImeConversionMode?メソッド
- InputMethod?.Current.ImeConversionMode?プロパティ
実装 †
以下は、IME制御のサンプルである。
- XAML
イベント ハンドラでIME制御する方法と、XAMLでIME制御する方法がある。
- 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;
}
}
説明 †
イベント ハンドラでのIME制御の動作は、
以下の点が、XAMLによるIME制御の場合と異なる。
- GotFocus?、LostFocus?イベントを扱っており、
GotFocus?イベントで現状のIME設定を保存し、
LostFocus?イベントでIME設定を復元している。
- このため、入力時のIME設定変更はLostFocus?イベントで無効になる。
参考 †
- MSDN > .NET Frameworkクラス ライブラリ
デザイナ向け機能 †
デザイナ向けの技術要素について説明する。
様々なシェイプ †
- Shapeクラスから派生するベクタ グラフィックス描画クラスには、次のものがある。
実装 †
- ただし、Visual StudioではPath 要素の編集が困難である。
このためExpression Blendのデザイナでは、[ペン]や[鉛筆]など、Path 要素の編集用ツールを使用すると良い。
以下は、Expression Blendデザイナの[ペン]や[鉛筆]を使用して記述したPath 要素の描画である。
- 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 に変換するといった機能も用意されている。
- この変換を行うには、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>
参考 †
- MSDN
- System.Windows.Shapes.Shapeクラス
- System.Windows.Shapes.Rectangleクラス
- System.Windows.Shapes.Ellipseクラス
- System.Windows.Shapes.Lineクラス
- System.Windows.Shapes.Polylineクラス
- System.Windows.Shapes.Pathクラス
グラデーション †
WPF / Silverlightでは、様々なグラデーションをデザイン可能。
実装 †
- 簡単なグラデーション
以下の簡素なグラデーションであれば、XAMLで直接記述することも可能。
- 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のデザイナを使用した方が、容易にグラデーションをデザインできる。
- 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>
トランスフォーム処理 †
- WPFで2D平面での変換を行う「トランスフォーム処理」を使用して以下の効果を追加できる。
- 「回転、拡大縮小、傾斜、平行移動」
- 「アニメーションなど一時効果」
- 「トランスフォーム処理」に使用できるクラスには、
System.Windows.Media名前空間のTransform クラスから派生する、下記クラスがある。
- MatrixTransform?
- RotateTransform?
- ScaleTransform?
- SkewTransform?
- TranslateTransform?
- TransformGroup?
- なお、TransformGroup?を使用すれば、
複数のTransformクラスを組み合わせて適用することができる。
- 以下、下記の図形に対する、上記2つの「トランスフォーム処理」の例。
回転、拡大縮小、傾斜、平行移動 †
- FrameworkElement?.LayoutTransform?プロパティに設定されたTransformクラスを使用し、
レイアウト時に「トランスフォーム処理」を実行する。
- このため、「トランスフォーム処理」後もUI要素がレイアウト時の描画領域内に収まる。
- このような特徴から、この「トランスフォーム処理」は、
表示を垂直から水平に切り替えたり、ズームしたりするなどの用途で利用可能である。
- 以下は、LayoutTransform?プロパティにRotateTransform?クラスを指定してUI要素を回転させた例である。
アニメーションなど一時効果の追加 †
- UIElement.RenderTransform?プロパティに設定されたTransformクラスを使用し、
レイアウト後に「トランスフォーム処理」しレンダリングする。
- このため、場合によってはUI要素がレイアウトの描画領域の外にでてしまう場合がある。
- このような特徴から、この「トランスフォーム処理」は、
「アニメーション」(後述)と組み合わせるなどしてUI要素に注目を集めるなどの用途で利用可能である。
- 以下は、RenderTransform?プロパティにRotateTransform?クラスを指定してUI要素を回転させた例である。
※ なお、こちらの「トランスフォーム処理」は「Silverlight」でもサポートされる。
参考 †
- MSDN
- System.Windows.Media.Transformクラス
アニメーション †
実装 †
説明 †
参考 †
MVVMデザイン パターン †
概要 †
MVVM(Model - View - View Model)モデルとは、
前述の「データ バインディング」の仕組みを活用したデザイン パターンであり、
従来の3層デザイン パターンの「モデル オブジェクト」、「ビュー オブジェクト」に加えて、
「バインディング ソース」である「ビュー・モデル オブジェクト」を新設するデザイン パターンである。
メリット †
このデザイン パターンのメリットは、
「モデル オブジェクト」、「ビュー オブジェクト」間の結合部を、
「データ バインディング」による「ビュー・モデル オブジェクト」に限定し、疎結合を実現できる点である。
ガイドライン †
なお、MVVMデザイン パターンのためのガイドライン には、以下のものがある。
- XAMLで実装できるものは、コードビハインドに実装しない。
- 「ビュー・モデル オブジェクト」はDataContext?として「ビュー オブジェクト」に渡す。
- 「ビュー・モデル オブジェクト」と「モデル オブジェクト」は、
「データ バインディング」により結合されるため、「ビュー オブジェクト」には、一切アクセスしない。
- 「ビュー・モデル オブジェクト」は、INotifyPropertyChanged?インターフェイスを実装するべき。
- 「ビュー・モデル オブジェクト」は、「モデル オブジェクト」をカプセル化することで、
「ビュー オブジェクト」から、データ ストレージの複雑さを隠蔽する。
参考 †
バリデーション †
- 以下をプロトタイプ開発したので参考にすることができる。
単項目のバリデーション †
https://github.com/OpenTouryoProject/SampleProgram/tree/master/UISubsystem/WPF/Validation/InputField
一覧のバリデーション †
https://github.com/OpenTouryoProject/SampleProgram/tree/master/UISubsystem/WPF/Validation/DataGrid
フォーカス制御 †
フォーカス制御については、いろいろ試しているが
問題が多いので使わない方向で考えた方が良さそう。
Tags: :.NET開発, :UIサブシステム, :WPF/Silverlight, XAML
|