画面のコードビハインド定義
画面定義がおわったら、次に画面定義に紐づいたコードを記述します。
ソリューションエクスプローラーで「MainWindow.xaml.vb」をダブルクリックすると、MainWindow.xamlと関連づいたコード(コードビハインド)を記述するためのコードエディタが開きます。
Class MainWindow Private ViewModel As New MainViewModel Public Sub New() InitializeComponent() Me.DataContext = Me.ViewModel End Sub End Class
WPFアプリでは、XAML側でボタンクリックしたときに呼び出すViewModelのプロパティを指定できるので、コードビハインドに記載が必要なコードはほとんどありません。
MainViewModelへの変更
Windowsフォームアプリを作成したときのMainViewModelクラスでは、ボタンクリック時にMainWindow.vbから呼び出されていたのはGetMailメソッドでした。XAMLからはICommandインターフェースを持ったプロパティにコマンドバインディングされて呼び出されるので、MainViewModelのGetMailメソッド部分を次のように書き換えます。
: (中略) : Public Async Function GetMail() As Task Await Me.Model.GetMail() End Sub : (中略) :
: (中略) : Private _GetMailCommand As Common.RelayCommand Public Property GetMailCommand() As Common.RelayCommand Get If _GetMailCommand Is Nothing Then _GetMailCommand = New Common.RelayCommand(AddressOf Me.GetMail) End If Return _GetMailCommand End Get Set(value As Common.RelayCommand) _GetMailCommand = value End Set End Property Private Async Sub GetMail() Await Me.Model.GetMail() End Sub : (中略) :
記述量は少し増えてしまうのですが、こうすることでXAML側とViewModelの関係はますます疎にできます。なお、Common.RelayCommandクラスはサンプルコードのCommonフォルダの中に新規作成していますので、詳しい内容はサンプルコードをダウンロードして確認してください。
実行結果の確認
それでは、実行結果を確認してみましょう。
残念ながらMailModelクラスの中で実行時エラーとなってしまいました。原因は、Windowsフォームのときと異なり、MailModelクラスのItemsはMainViewModelを介してMainWindowのListBoxにBindingされている点です。つまり、非同期実行しているmes.Get(0)実行時に発生するProgressイベントの処理の中でMe.Items.Addすると、それはUIスレッドでXAMLが更新することになり、非同期スレッドからUIスレッドというスレッド間の連携が生じてしまうからです。
そのため、PopProgressイベントプロシージャの中を次のように書き換えることで解決ができます。
: (中略) : Private Context As SynchronizationContext = SynchronizationContext.Current : (中略) : Private Sub PopProgress(sender As Object, e As Dart.Mail.PopProgressEventArgs) If e.Final Then Me.Context.Post(Sub(o) Me.Items.Add(New TMail With { .From = e.Message.Message.From, .Subject = e.Message.Message.Subject, .SendDate = e.Message.Message.Date }) End Sub, Nothing) End If End Sub : (中略) :
それでは再度、実行結果を確認してみましょう。
今度は正常に表示できました。もちろん文字化けすることもまったくなく、一覧が作成されています。