2013年05月28日

WPFサンプル:ICommand インターフーイスを実装してカスタムコマンドを作成する

   このエントリーをはてなブックマークに追加 Clip to Evernote
前回は、標準のコマンドを使う例をお見せしましたが、ICommandインターフェースを実装すれば独自のコマンドクラスを作成することができます。ICommandインターフェースには、ExecuteとCanExecuteの2つのメソッドと、CanExecuteChangedイベントが定義されています。

ここでは、MessageBoxを表示するだけの簡単なコマンドを作成してみます。


このMyCommandを使ったXAMLを示します。


Commandプロパティには、Window.Resourcesで定義したMyCommandをバインドし、CommandParameterには、TextBoxで入力されたTextプロパティをバインドしています。
ボタンが押されると、MyCommandのExecuteメソッドが呼ばれます。
引数には、textBox1.Textの値が渡ってきます。
MainWindow.Xaml.csにはコードを追加する必要はありません。

実行結果です。
TextBoxに何らかの文字列が入力されているときだけ、ボタンが有効になっているのが確認できます。

ICommand1 Icommand2 ICommand3
  

Posted by gushwell at 23:00Comments(0)TrackBack(0)

2013年05月26日

WPFサンプル:標準のコマンドを使う

   このエントリーをはてなブックマークに追加 Clip to Evernote
WPFでは、プレゼンテーション層から何かの機能を呼び出す目的のために、イベントハンドラとは別に、「コマンド」という仕組みを用意しています。コマンドを使うと、イベントハンドラよりも、ロジックと見た目の結合度を低くすることができます。コマンドの例として代表的なものは、「コピー」、「切り取り」、「貼り付け」、「開く」、「印刷」などがあります。

標準のコマンドを使った簡単なサンプルを書いてみました。

まずはXAMLです。


このサンプルでは、ApplicationCommands.Cut、ApplicationCommands.Copy、ApplicationCommands.Paste、ApplicationCommands.Openを使っています。

Cut, Copy, Pasteでは、コマンドが実行できない状況では、メニュー項目は自動的に無効になります。TextBoxコントロールにはCopyコマンド等を処理するためのロジックが組み込まれているため、特別なコードを書かなくても、Commandを指定するだけで機能するようになります。

ApplicationCommands.Openでは、CommandBindingを使い、Executeプロパティで、Commandとイベントハンドラを結び付けています。
CommandBinding CanExecuteプロパティは、コマンドが実行できるかどうかを判断するメソッドと結び付けます。
ここでは、C#のコードで、無条件に trueを返していますが、falseを返せば、関連しているコントロールがDisable状態になります。

C#のコードを以下に示します。
ApplicationCommands.Openと関連づけられたOpenCmdExecutedメソッドでは、OpenFileDialogを使い、ユーザが指定したファイルを読み込み、TextBoxに表示しています。


実行時のスクリーンショットです。

StandardCommand1

StandardCommand2

この他にも、 ApplicationCommands、NavigationCommands、MediaCommands、EditingCommands、ComponentCommands など多くのコマンドが定義済みです。詳細はMSDNを参照してください。  
Posted by gushwell at 22:30Comments(0)TrackBack(0)

2013年05月23日

WPFサンプル:イベントを発生させた要素を知る

   このエントリーをはてなブックマークに追加 Clip to Evernote
RoutedEventArgsのSourceプロパティを参照することで、どの要素がイベントを発生させたのかがわかります。

まずは、サンプルのXAMLとその画面を示します。


ButtonのContentは、StackPanelが設定されており、StackPanelには、Image, TextBlockが配置されています。
このButtonが右クリックされたときに、どの要素でクリックされたのかを表示するC#のコードを書いてみました。
実行すると、Image,TextBlockの部分を右クリックした場合は、その要素名がTextBlockに表示されます。
ボタンの中の Image,TextBlock 以外をクリックすると Button直接右クリックされたことを確認できます。


併せて、RoutedEventArgs のHandledプロパティの動きも確認するコードも記述しています。
CheckBoxがチェックされていた場合、Image_MouseLeftButtonDown で、Handled プロパティをtrueにしているので、そのイベントがButtonに伝搬しません。

以下実行時のスクリーンショットです。上記の説明と併せてご覧ください。

■ボタンを右クリックした時のスクリーンショット

RoutedEventArgs1 RoutedEventArgs2 RoutedEventArgs3

■ボタンをクリック(左クリック)した時のスクリーンショット

RoutedEventArgs4 RoutedEventArgs5 RoutedEventArgs6

すべてTextBoxをクリアしてからクリックしています。

--------
WPFサンプル・目次
  
Posted by gushwell at 23:00Comments(0)TrackBack(0)

2013年05月21日

WPFサンプル:添付イベントを使用する。

   このエントリーをはてなブックマークに追加 Clip to Evernote
添付イベントを使用すると、複数のボタンがありそのクリックイベントに対応するイベントハンドラを一つにまとめたいといった要求に簡単に応えることができます。
まずは、XAMLを見てください。


StackPanelに、Button.Click="Button_Click" という記述がありますね。これが添付イベントです。
StackPanelには、ボタンのClickイベントというのは存在しませんが、StackPanelの子(孫)要素として定義されているButtonでClickされた時に発生するイベントに応答することができます。

この例では、3つのボタンがありますが、この3つのボタンがClickされると、Button_Clickメソッドが呼び出されます。

これを添付イベントと言います。このような記述はすべてのイベントで利用できるわけではありません。
一部のイベントのみが添付イベントとして利用できます。その一部を以下に示します。
 ButtonBase.Click
 Control.MouseDoubleClick
 RangeBase.ValueChanged
 Selector.Selected
 TextBoxBase.TextChanged

Button_Clickイベントハンドラの例と、その実行例を示します。
RoutedEventArgs.Sourceを参照することで、どこで発生したイベント化を判断できます。
senderで判断してはいけません。


AttachedEvent
  
Posted by gushwell at 21:31Comments(0)TrackBack(0)

2013年05月16日

WPFサンプル:KeyDownイベントとKeybord.Modifiersプロパティ

   このエントリーをはてなブックマークに追加 Clip to Evernote
WindowsFormsでおなじみの KeyDownイベントは、WPFでも利用できます。
このイベントを利用すれば、特定のキーが押されたかどうかを判定することができます。
ここでは、KeyDownイベント と PreviewKeyDown イベントの簡単なサンプルを書いてみました。
TextBoxで押されたキーの情報をTextBlockに表示しています。また、その親であるStackPanelでのKeyDownイベント と PreviewKeyDown イベントも処理しています。
いつものように、まずはXAMLを示します。


次にC#のコードを示します。


このサンプルコードでは、それぞれのプロパティの型がわかるように、一時変数に代入しています。その時に押されたキーの情報は、KeyEventArgsから得られますが、これだけだと、Shiftキーが一緒に押されているかといった情報を得られません。それには、KeybordクラスのModifiers staticプロパティを見る必要があります。コードの後半部分ではその判定を行っています。

ちなみに、KeybordクラスのModifiers静的プロパティは、KeyDownイベントハンドラ以外でも利用できますので、Shiftキーを押しながら、マウスをクリックしたかどうかという判定に利用することもできます。
実行してみるとわかりますが、TextBoxにフォーカスがある場合でも、CheckBoxにフォーカスがある場合でも、キーが押されると、StackPanelのKeyDownイベント と PreviewKeyDown イベントが発生するのが確認できます。
また、PrevirewKeyDownでは、IMEがOnの状態で押されたキーも確認できます。

TextBox上でShift+aを押したところ。
KeyDown1

TextBox上で、Alt+Sを押したところ。
KeyDown2

CheckBoxにフォーカスを当て、Fを押したところ
KeyDown3

  
Posted by gushwell at 23:30Comments(0)TrackBack(0)

2013年05月14日

WPFサンプル:マウスポインタの移動を感知する

   このエントリーをはてなブックマークに追加 Clip to Evernote
マウスカーソルに追随して、コントロールが移動するコードを書いてみました。

MouseCapture1

MouseCapture3

まずは、XAML。


Canvas の中に、Ellipse を配置します。Ellipse では、Fill で塗りつぶしの色を設定しています。これがないと、Ellipse でのマウス関連のイベントを拾うことができません。WPF では、Ellipse に限らず、Background やFillが未設定だと、非表示状態であるという認識になり、マウスイベントを受け取れなくなるようです。

ここでは3つのイベントハンドラを設定しています。マウスが動いているかどうかは、MouseMove イベントだけを見ればよいのですが、この例では、マウスボタンが押されている時だけ処理をさせたいので、MouseDown,MouseUp イベントも使います。

では、C#です。


ここでは、CaptureMouse()がカギです。これが無いと、素早くマウスを動かしたときに、マウスカーソルが、Ellipse の外側に動いていしまい、Ellipse では、MouseMOve, MouseUp イベントを拾うことが出来ずに、移動がマウスに追随しなくなってしまいます。
CaptureMouse で、マウスを強制的に捕捉し続けるようにし、移動を終了する時に、ReleaseMouseCapture で、捕捉を終了しています。

  
Posted by gushwell at 23:00Comments(0)TrackBack(0)

2013年05月12日

WPFサンプル:領域にマウスポインタが入ったかどうかを検出する

   このエントリーをはてなブックマークに追加 Clip to Evernote
2Dグラフィックスの話題も一段落したので、また初歩的な話題に戻ってWPFのサンプルコードの紹介を続けていこうと思います。

今回は、WinddowsForms にもある、MouseEnter, MouseLeave イベントを使ったサンプルコードを示します。
MouseEnter、MouseLeaveイベントは、UIElementクラスに存在しますので、Panel、Imageなども含め、すべてのUIElementの派生クラスで利用できます。
ここでは、Rectangleの領域にマウスが入った時と領域を出た時に処理をするコードを書いてみました。
MouseEnter1 MouseEnter2

まずはXAML



特に特筆すべき点はありません。
以下、C#のコードです。

MouseEnterイベントハンドラでは、現在のFillプロパティの値を記憶し、 Colors.BrownでRectangleを塗りつぶしています。
MouseLeaveでは、先ほど記憶したFillの値で、Rectangleの色をもとに戻しています。


これと同じことは、PropertyTriggerを使っても実現可能です。
機会があれば紹介したいと思います。

  
Posted by gushwell at 23:00Comments(0)TrackBack(0)

2013年05月09日

WPFサンプル:鏡面反射

   このエントリーをはてなブックマークに追加 Clip to Evernote
これまでのサンプルプログラムで示してきた VisualBrush OpacityMask BlurEffect を使うことで、鏡面反射の効果を出すことができます。

SpecularRef

以下、そのXAMLです。C#でのコード追加はありません。
VisualBrush の Visual プロパティで、反射されるオブジェクトをバインドしています。

  
Posted by gushwell at 23:30Comments(0)TrackBack(0)