概要
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”]
<Window x:Class="MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:my="clr-namespace:WpfAppEventTest"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<my:disp1 x:Key="disp1" />
</Window.Resources>
<Grid>
<StackPanel x:Name="Panel1" Loaded="Panel1_Loaded" Keyboard.KeyDown="TextBox_KeyDown" KeyUp="TextBox_KeyUp">
<TextBox Text="{Binding Source={StaticResource disp1}, Path=input1, Mode=TwoWay}" BorderBrush="Blue" Margin="10"/>
<TextBox Text="{Binding Source={StaticResource disp1}, Path=input2, Mode=TwoWay}" BorderBrush="Red" Margin="10" />
<TextBox Text="{Binding Source={StaticResource disp1}, Path=input3, Mode=TwoWay}" BorderBrush="Green" Margin="10"/>
<TextBlock Text="{Binding Source={StaticResource disp1}, Path=sumdata, Mode=OneWay}"/>
<TextBlock Text="{Binding Source={StaticResource disp1}, Path=avedata, Mode=OneWay}"/>
<Button Content="Calc" Click="Button_Click"/>
</StackPanel>
</Grid>
</Window>
[/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