概要
WPFで独自クラスをインスタンス化する場合、次の二つの方法があります。
- 従来のWindowsフォームのようにコードビハインドでインスタンス化する方法
- XAMLでリソース定義をしてインスタンス化する方法
コードビハインドでインスタンス化したクラスを呼び出す場合、上記1.の方法は問題ありませんが、上記2.のXAMLでインスタンス化された独自クラスの呼び出し方はWPF特有ですのでメモしておきます。
環境
Microsoft Visual Studio 2015 + WPF + VB
XAMLのリソースを定義または参照する方法
独自クラス
XAMLでのリソース定義
WPFでは、XAMLでリソースを定義(クラスの場合はインスタンス化)できます。その方法は、Resoucesタグにインスタンス化したいクラスの名称とそれを参照するためのキーを登録するだけです。
[code lang=”html”]<my:対象のクラス名 x:Key=”参照するためのキー” />[/code]
XAMLでリソース参照
XAMLから参照する場合は、次のように参照した内容を設定したいコントロールのプロパティにバインディングさせることで可能です。
ここでは、Sourceに先ほど定義したリソース(クラス)のキーを、pathにはリソース(クラス)のプロパティを設定します。Modeには該当のコントロールのプロパティに値を設定するだけであればoneWay(単方向)を、値を設定または参照する場合はTwoWay(双方向)を指定します。
コードビハインドでリソース参照
リソースに定義済みのクラスのメソッドを呼び出すときはResoucesプロパティまたはFindResourceメソッドを使用します。Resourcesプロパティの場合は、カッコ内にリソース名を設定するとリソースの参照が可能となり、コードビハインドでクラスを呼び出すことができるようになります。
Resourcesプロパティを使用する場合
[code lang=”vb”]Me.Resources(“リソースのキー“).プロパティまたはメソッド[/code]
FindResourceメソッドを使用する場合
[code lang=”vb”]Me.FindResource(“リソースのキー“).プロパティまたはメソッド[/code]
数値や文字列(名前空間systemで定義されたクラス)
数値や文字列をXAMLでリソース定義および参照する場合は、Window定義における「xmlns:system=”clr-namespace:System;assembly=mscorlib”」は、コアアセンブリ(mscorlib)のSystem名前空間に対応するXML中の名前空間”system”を定義する必要があります。
XAMLでのリソース定義
WPFでは、XAMLでリソースを定義(クラスの場合はインスタンス化)できます。その方法は、Resoucesタグにインスタンス化したいクラスの名称とそれを参照するためのキーを登録するだけです。
[code lang=”html”]<system:数値または文字列の型のクラス※ x:Key=”参照するためのキー“>数値または文字列</system:数値または文字列の型のクラス※>[/code]
※数値または文字列の型のクラスにはInteger,Double,String等の型クラス
XAMLでリソース参照
XAMLから参照する場合は、次のように参照した内容を設定したいコントロールのプロパティにバインディングさせることで可能です。
ここでは、Sourceに先ほど定義したリソース(クラス)のキーを、pathにはリソース(クラス)のプロパティを設定します。Modeには該当のコントロールのプロパティに値を設定するだけであればoneWay(単方向)を、値を設定または参照する場合はTwoWay(双方向)を指定します。
コードビハインドでリソース参照
リソースに定義済みのクラスのメソッドを呼び出すときは次のようにResoucesプロパティを使用します。Resourcesプロパティのカッコ内にリソース名を設定するとリソースの参照が可能となり、コードビハインドでクラスを呼び出すことができるようになります。
[code lang=”vb”]Me.Resources(“リソースのキー“)[/code]
サンプル
説明
画面に入力用の3つのテキストボックスと2つの出力用テキストボックスを配置します。
3つのテキストボックスに入力された数値の総合計と平均を2つのテキストボックスにそれぞれ出力します。
総合計と平均のテキストボックスは、それぞれ合計を取得するsumdataプロパティと平均を取得するavedataプロパティがバインディングされています。3つのいずれかのテキストボックスの内容が入力されると、再計算された値が表示されます。
Calcボタンをクリックすると、リソース(クラス)のsumdataプロパティを参照して合計を表示します。
ちなみに、コードビハインドではリソース(クラス)のメソッドやファンクションを直接呼び出すこともできます。
スクリーンショット
スクリプト
XAML
[code lang=”HTML”][/code]
MainWindowクラス(コードビハインド)
[code lang=”vb”]Class MainWindow Dim clss_disp1 As disp1 Private Sub TextBox_KeyDown(sender As System.Object, e As System.Windows.Input.KeyEventArgs) End Sub Private Sub TextBox_KeyUp(sender As System.Object, e As System.Windows.Input.KeyEventArgs) End Sub Private Sub Panel1_Loaded(sender As System.Object, e As System.Windows.RoutedEventArgs) clss_disp1 = New disp1 Panel1.DataContext = clss_disp1 End Sub Private Sub Button_Click(sender As System.Object, e As System.Windows.RoutedEventArgs) REM XAMLで定義したリソースを呼び出して使用する Me.Resources("disp1").calc() 'WINDOWSリソースに定義したsumdataプロパティを参照して表示する MessageBox.Show("合計は" + Me.Resources("disp1").sumdata.ToString) End Sub End Class[/code]
合計値と平均値を計算する独自クラス
[code lang=”vb”]Imports System.ComponentModel Public Class disp1 Implements INotifyPropertyChanged Private _input1 As Integer Private _input2 As Integer Private _input3 As Integer Private _sumdata As Integer Private _avedata As Integer Public Sub New() Me._input1 = 0 Me._input2 = 0 Me._input3 = 0 Me._sumdata = 99 Me._avedata = 999 End Sub Public Property input1() As Integer Get Return _input1 End Get Set(value As Integer) _input1 = value Me.calc() End Set End Property Public Property input2() As Integer Get Return _input2 End Get Set(value As Integer) _input2 = value Me.calc() End Set End Property Public Property input3() As Integer Get Return _input3 End Get Set(value As Integer) _input3 = value Me.calc() End Set End Property Public Property sumdata() As Integer Get Return _sumdata End Get Private Set(value As Integer) _sumdata = value OnPropertyChanged("sumdata") End Set End Property Public Property avedata() As Integer Get Return _avedata End Get Private Set(value As Integer) _avedata = value OnPropertyChanged("avedata") End Set End Property Public Sub calc() sumdata = input1 + input2 + input3 avedata = sumdata / 3 End Sub Public Event PropertyChanged(sender As Object, e As System.ComponentModel.PropertyChangedEventArgs) Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged Protected Overridable Sub OnPropertyChanged(ByVal propertyNane As String) RaiseEvent PropertyChanged( _ Me, New PropertyChangedEventArgs(propertyNane)) End Sub End Class[/code]
まとめ
WPFではコードビハインドでプログラムを書かなくてもすべてXAMLで処理することができるそうです。どちらも同じように使えると、コードを書くときにどちらがいいか迷ったり、また人によって書き方がまちまちだったりするので考えものです。プロジェクトでWPFを使う場合は、そのあたりをメンバー間で話し合ってコーディング規約に反映する必要がありそうです。
関連記事
参考
リソースとコード
https://msdn.microsoft.com/ja-jp/library/ms752326(v=vs.110).aspx
WPFのStaticResourceとDynamicResourceの違い
WPFのStaticResourceとDynamicResourceの違い
(XAML#04)「リソースで数値や文字列を定義する」
http://blogs.itmedia.co.jp/mohno/2013/12/xaml04-170d.html
WPFサンプル:独自クラスをResourcesに指定し、StaticResourceで参照する
http://gushwell.ldblog.jp/archives/52299560.html
WPF4.5入門 その51 「リソース」
WPF 個人用メモ.1※WPF
http://diy.sinceretechnology.work/wp-admin/post.php?post=18061&action=edit
App.xamlで定義したリソースを動的に変更したい
http://d.hatena.ne.jp/hilapon/20151113/1447381150
リソースの使い方
http://ex.osaka-kyoiku.ac.jp/~fujii/WPFhp/WPF_resources.html
WPFのStaticResourceとDynamicResourceの違い – MSDN – Microsoft
https://social.msdn.microsoft.com/Forums/ja-JP/3bbcdc48-2a47-495e-9406-2555dc515c3a/wpfstaticresourcedynamicresource?forum=wpfja