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

posted @ 2011-07-05 15:04  焦涛  阅读(931)  评论(0)    收藏  举报