我使用委托从 ViewModel 到 View 进行通信。让我解释。在我的框架中,我有这个抽象类:
public abstract class NotificationObject : INotifyPropertyChanged
{
// very usefull to order view (if exist) to close
public delegate void ActionClose(Boolean closeResult);
public delegate void ActionUpdate();
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void RaisePropertyChanged(string propertyName)
{
// take a copy to prevent thread issues
PropertyChangedEventHandler handler = this.PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
// other implementation for RaisePropertyChange (not the point here)
// protected virtual void RaisePropertyChanged(params string[] propertyNames)
// protected virtual void RaisePropertyChanged<T>(Expression<Func<T>> propertyExpression)
}
现在,我所有的 ViewModel 都可以从 NotificationObject 继承
public class MyViewModel : NotificationObject
{
public MyViewModel ()
{
// initialisation
}
// bindable action UI -> VM
public ICommand Command1 { get; set; }
public ICommand Command2 { get; set; }
// VM -> View
public ActionUpdate Action1 { get; set; }
public ActionUpdate Action2 { get; set; }
// in this method, we need to "notify" view that it must do something (refresh, close, modify UI ...)
private void MyMethod()
{
// never forget that UI can not exist (testing for exemple), or not UI (command-line process), so Action1 can be null
if (this.Action1 != null)
{
this.Action1 ();
}
}
}
现在,在 View 中,我们可以声明委托(在 Window_Loaded 中,已加载 ViewModel):
private void Window_Loaded(object sender, RoutedEventArgs e)
{
MyViewModel context = this.DataContext as MyViewModel ;
if (context != null)
{
NotificationObject.ActionUpdate myAction1 = new NotificationObject.ActionUpdate(this.MyAction1);
context.Action1 = myAction1 ;
NotificationObject.ActionUpdate myAction2 = new NotificationObject.ActionUpdate(this.MyAction2);
context.Action2 = myAction2 ;
}
}
private void MyAction1()
{
// do something
}
private void MyAction2()
{
// do something
}
就这样。^^