本节结束了Prism中Commanding QuickStart这个项目,主要讲解了CompositeCommand和DelegateCommand。CompositeCommand往往来出来一批命令,就像下面的Order,你可以填写一个订单后,就保存这个订单。你可以一个订单,但不保存,继续天下一个订单,最后点击一个按钮SaveAllOrders,把所填的所有订单一次性全部保存。
首先我们来看看OrderModule,它是一个模块,代码如下:
通过使用DelegateCommand,你可以为Execute和CanExecute方法提供委托。
(1)在OrderPresentationModel.cs文件中 SaveOrderCommand的委托命令被创建
{
_order = order;
//TODO: 01 - Each Order defines a Save command.
this.SaveOrderCommand = new DelegateCommand<object>( this.Save, this.CanSave );
// Track all property changes so we can validate.
this.PropertyChanged += this.OnPropertyChanged;
this.Validate();
}
(2)对应的DelegateCommand委托方法
{
// TODO: 02 - The Order Save command is enabled only when all order data is valid.
// Can only save when there are no errors and
// when the order quantity is greater than zero.
return this .errors.Count == 0 && this .Quantity > 0 ;
}
private void Save( object obj )
{
// Save the order here.
Console.WriteLine(
String.Format( CultureInfo.InvariantCulture, " {0} saved. " , this .OrderName ) );
// Notify that the order was saved.
this .OnSaved( new DataEventArgs < OrderPresentationModel > ( this ) );
}
(3)OrdersCommands.xaml.cs中顶一个静态类OrdersCommands来封装静态的CompositeCommand实例。并且封装OrdersCommandProxy作为代理类,封装了属性
{
/// <summary>
/// Defines the SaveAll command. This command is defined as a static so
/// that it can be easily accessed throughout the application.
/// </summary>
public static class OrdersCommands
{
// TODO: 03 - The application defines a global SaveAll command which invokes the Save command on all registered Orders. It is enabled only when all orders can be saved.
// 定义CompositeCommand用来保存所有没有保存的订单
public static CompositeCommand SaveAllOrdersCommand = new CompositeCommand();
}
/// <summary>
/// Provides a class wrapper around the static SaveAll command.
/// </summary>
public class OrdersCommandProxy
{
public virtual CompositeCommand SaveAllOrdersCommand
{
get { return OrdersCommands.SaveAllOrdersCommand; }
}
}
}
(4)在OrdersEditorPresentationModel.cs中对OrdersCommandProxy进行代码的调用
/// Presentation model to support the OrdersEditorView.
/// </summary>
public class OrdersEditorPresentationModel : INotifyPropertyChanged
{
private readonly IOrdersRepository ordersRepository;
private readonly OrdersCommandProxy commandProxy;
private ObservableCollection < OrderPresentationModel > _orders { get ; set ; }
public OrdersEditorPresentationModel( IOrdersRepository ordersRepository, OrdersCommandProxy commandProxy )
{
this .ordersRepository = ordersRepository;
this .commandProxy = commandProxy;
// Create dummy order data.
this .PopulateOrders();
// Initialize a CollectionView for the underlying Orders collection.
#if SILVERLIGHT
this .Orders = new PagedCollectionView( _orders );
#else
this .Orders = new ListCollectionView( _orders );
#endif
// Track the current selection.
this .Orders.CurrentChanged += SelectedOrderChanged;
this .Orders.MoveCurrentTo( null );
}
public ICollectionView Orders { get ; private set ; }
private void SelectedOrderChanged( object sender, EventArgs e )
{
SelectedOrder = Orders.CurrentItem as OrderPresentationModel;
NotifyPropertyChanged( " SelectedOrder " );
}
public OrderPresentationModel SelectedOrder { get ; private set ; }
private void PopulateOrders()
{
_orders = new ObservableCollection < OrderPresentationModel > ();
foreach ( Services.Order order in this .ordersRepository.GetOrdersToEdit() )
{
// Wrap the Order object in a presentation model object.
var orderPresentationModel = new OrderPresentationModel( order );
_orders.Add( orderPresentationModel );
// Subscribe to the Save event on the individual orders.
orderPresentationModel.Saved += this .OrderSaved;
// TODO: 04 - Each Order Save command is registered with the application's SaveAll command.
// 每个Order的Save commnad被注册到了应用程序的SaveAll command
commandProxy.SaveAllOrdersCommand.RegisterCommand( orderPresentationModel.SaveOrderCommand );
}
}
// Saved事件方法
// class DataEventArgs<TData> : EventArgs 包含一个构造函数DataEventArgs(TData value)和属性TData Value { get; }
private void OrderSaved( object sender, DataEventArgs < OrderPresentationModel > e )
{
if (e != null && e.Value != null )
{
OrderPresentationModel order = e.Value;
if ( this .Orders.Contains( order ) )
{
// 取消OrderSaved事件方法
order.Saved -= this .OrderSaved;
// 当某一个订单已经被保存,就应在SaveAllOrdersCommand取消改保存,以免重复保存
this .commandProxy.SaveAllOrdersCommand.UnregisterCommand( order.SaveOrderCommand );
// 从订单集合中移除该订单(表示保存陈宫)
this ._orders.Remove( order );
}
}
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged( string propertyName )
{
if ( this .PropertyChanged != null )
{
this .PropertyChanged( this , new PropertyChangedEventArgs( propertyName ) );
}
}
#endregion
}
(5)在OrdersEditorView.xaml中,SaveButton按钮的绑定
(6)在OrdersToolBar.xaml,SaveAllToolBarButton按钮绑定
(7)程序运行界面截图:
(8)项目组织结构截图:
(9)后续关于改项目的模块介绍
OrderModuled的介绍
{
private readonly IRegionManager regionManager;
private readonly IUnityContainer container;
public OrderModule( IUnityContainer container, IRegionManager regionManager )
{
this .container = container;
this .regionManager = regionManager;
}
public void Initialize()
{
// 将具体类OrdersRepository与之对应的IOrdersRepository关联,实现IOC(控制反转或者叫依赖注入)来解耦
this .container.RegisterType < IOrdersRepository, OrdersRepository > ( new ContainerControlledLifetimeManager());
// this.container.Resolve<OrdersEditorView>()将具体OrdersEditorView控件从容器中解耦,
// RegisterViewWithRegion将解耦出来OrdersEditorView控件注册到相应的MainRegion中
this .regionManager.RegisterViewWithRegion( " MainRegion " ,
() => this .container.Resolve < OrdersEditorView > () );
// this.container.Resolve<OrdersToolBar>()将具体的OrdersToolBar控件从容器中解耦,
// RegisterViewWithRegion将解耦出来OrdersToolBar控件注册到相应的GlobalCommandsRegion中
this .regionManager.RegisterViewWithRegion( " GlobalCommandsRegion " ,
() => this .container.Resolve < OrdersToolBar > () );
}
}
在看看CommandingBootstrapper.cs中代码
{
protected override DependencyObject CreateShell()
{
return Container.Resolve < Shell > ();
}
protected override void InitializeShell()
{
base .InitializeShell();
#if SILVERLIGHT
App.Current.RootVisual = (UIElement) this .Shell;
#else
App.Current.MainWindow = (Window) this .Shell;
App.Current.MainWindow.Show();
#endif
}
protected override void ConfigureModuleCatalog()
{
base .ConfigureModuleCatalog();
ModuleCatalog moduleCatalog = (ModuleCatalog) this .ModuleCatalog;
moduleCatalog.AddModule( typeof (OrderModule));
}
}
在看看Shell.xaml