Prism学习笔记(四):Commanding
本节结束了Prism中Commanding QuickStart这个项目,主要讲解了CompositeCommand和DelegateCommand。CompositeCommand往往来出来一批命令,就像下面的Order,你可以填写一个订单后,就保存这个订单。你可以一个订单,但不保存,继续天下一个订单,最后点击一个按钮SaveAllOrders,把所填的所有订单一次性全部保存。
首先我们来看看OrderModule,它是一个模块,代码如下:
通过使用DelegateCommand,你可以为Execute和CanExecute方法提供委托。
(1)在OrderPresentationModel.cs文件中 SaveOrderCommand的委托命令被创建
public OrderPresentationModel( Services.Order order )
{
_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委托方法
private bool CanSave( object arg )
{
//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作为代理类,封装了属性
namespace Commanding.Modules.Order
{
/// <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进行代码的调用
/// <summary>
/// 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按钮的绑定
<Button Grid.Row="6" Grid.Column="1" Content="Save" prism:Click.Command="{Binding Path=SaveOrderCommand}" AutomationProperties.AutomationId="SaveButton" />
(6)在OrdersToolBar.xaml,SaveAllToolBarButton按钮绑定
<Button AutomationProperties.AutomationId="SaveAllToolBarButton" prism:Click.Command="{Binding SaveAllOrdersCommand}" Content="Save All Orders" Width="120" />
(7)程序运行界面截图:

(8)项目组织结构截图:

(9)后续关于改项目的模块介绍
OrderModuled的介绍
public class OrderModule : IModule
{
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中代码
public class CommandingBootstrapper : UnityBootstrapper
{
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

浙公网安备 33010602011771号