ビューとロジックの橋渡し部分の作成
お次はMainWindow(ビュー)とCounterModel(ロジック)との仲介役となるMainWindowViewModelをVBで実装します。MainWindowsViewModelはMainWindowからバインドされるため、インターフェース:INotifyPropertyChangedを実装(Implements)しなければなりません。カウント値(Countプロパティ)の変更はイベント:NotifyPropertyChangedによってビューに通知されます。また、MainWindowの+/-ボタンにバインドされたIncCommand/DecCommandについてはそのままCounterModelに横流しするための「中継ぎ」になっています。
Imports System.ComponentModel
Imports System.Windows.Input
Namespace DataBindingSample
Public Class MainWindowViewModel
Implements INotifyPropertyChanged
Public Property Count() As Integer
Get
Return count_
End Get
Set(ByVal value As Integer)
count_ = value
RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs("Count"))
End Set
End Property
Public Event PropertyChanged As PropertyChangedEventHandler _
Implements INotifyPropertyChanged.PropertyChanged
Public Sub Update(ByVal c As Integer)
Count = c
End Sub
Public Property IncCommand() As ICommand
Public Property DecCommand() As ICommand
Private count_ As Integer
End Class
End Namespace
もう一仕事、MainWindowViewModelのIncCommand/DecCommandと、CounterModelのIncrement/Decrementとを繋がにゃならんのですが、双方の型がICommandとAction<Object>なので変換アダプタ:DelegateCommandをC++/CLIで書きました。
#ifndef DELEGATECOMMAND_H__
#define DELEGATECOMMAND_H__
namespace DataBindingSample {
public ref class DelegateCommand : public System::Windows::Input::ICommand {
public:
DelegateCommand(System::Action<Object^>^ execute);
DelegateCommand(System::Action<Object^>^ execute, System::Func<Object^, bool>^ canExecute);
virtual void Execute(Object^ parameter);
virtual bool CanExecute(Object^ parameter);
virtual event System::EventHandler^ CanExecuteChanged;
private:
System::Action<Object^>^ execute_;
System::Func<Object^, bool>^ canExecute_;
static bool alwaysTrue(Object^ arg);
};
}
#endif
#include "DelegateCommand.h"
using namespace System;
using namespace System::Windows::Input;
namespace DataBindingSample {
DelegateCommand::DelegateCommand(Action<Object^>^ execute) {
execute_ = execute;
canExecute_ = gcnew Func<Object^,bool>(DelegateCommand::alwaysTrue);
}
DelegateCommand::DelegateCommand(Action<Object^>^ execute, Func<Object^, bool>^ canExecute) {
execute_ = execute;
canExecute_ = canExecute;
}
bool DelegateCommand::CanExecute(Object^ parameter) { return canExecute_(parameter); }
void DelegateCommand::Execute(Object^ parameter) { execute_(parameter); }
bool DelegateCommand::alwaysTrue(Object^ arg) { return true; }
}
