外贸网站租用外国服务器好还是自己装一个服务器好,数据库 搭建 网站,如何网站建设平台,梯子国外服务器Prism Commands 1.复合命令#xff08;Composite Commanding#xff09;
这段内容主要介绍了在应用程序中如何使用复合命令#xff08;Composite Commands#xff09;来实现多个视图模型#xff08;ViewModels#xff09;上的命令。以下是对这段内容的解释#xff1a; …Prism Commands 1.复合命令Composite Commanding
这段内容主要介绍了在应用程序中如何使用复合命令Composite Commands来实现多个视图模型ViewModels上的命令。以下是对这段内容的解释
1.1. 复合命令的概念
在许多情况下ViewModel中定义的命令会绑定到相关视图中的控件上这样用户就可以直接在视图中调用这些命令。然而在某些情况下你可能希望从一个父视图中的控件调用一个或多个ViewModel上的命令。
1.2. 复合命令的应用场景
例如如果你的应用程序允许用户同时编辑多个项目你可能希望允许用户使用应用程序工具栏或功能区中的单个按钮来保存所有项目。在这种情况下保存全部命令将调用每个项目的ViewModel实例实现的保存命令。
1.3. Prism框架对复合命令的支持
Prism框架通过CompositeCommand类支持这种场景。CompositeCommand类表示由多个子命令组成的命令。当复合命令被调用时会依次调用每个子命令。它适用于需要在UI中将一组命令表示为单个命令的情况或者当你想要调用多个命令以实现一个逻辑命令时。
1.4. CompositeCommand类的工作原理
CompositeCommand类维护一个子命令列表DelegateCommand实例。CompositeCommand类的Execute方法简单地依次调用每个子命令的Execute方法。CanExecute方法类似地调用每个子命令的CanExecute方法但如果任何一个子命令不能执行CanExecute方法将返回false。换句话说默认情况下只有当所有子命令都可以执行时CompositeCommand才能被执行。
1.5. CompositeCommand类的位置
CompositeCommand可以在Prism.Commands命名空间中找到该命名空间位于Prism.Core NuGet包中。
2.创建一个复合命令
复合命令是由多个子命令组成的命令当复合命令被触发时它的每个子命令会依次被执行。这在用户界面UI中表示一组命令为单个命令或者想要执行多个命令以实现一个逻辑命令时非常有用。
具体来说创建复合命令的步骤
实例化一个 CompositeCommand 对象。将这个 CompositeCommand 对象作为一个属性暴露出来这个属性可以是 ICommand 或者 CompositeCommand 类型。
下面是具体的代码示例
public class ApplicationCommands
{// 创建一个私有的 CompositeCommand 实例private CompositeCommand _saveCommand new CompositeCommand();// 将这个实例作为一个公共属性暴露出来允许外部访问和使用这个复合命令public CompositeCommand SaveCommand{get _saveCommand;}
}在这个例子中ApplicationCommands 类包含了一个名为 SaveCommand 的属性这个属性是一个 CompositeCommand 类型的实例。这样你就可以在应用程序的任何地方通过 ApplicationCommands.SaveCommand 来访问和使用这个复合命令例如将其绑定到用户界面的按钮上当按钮被点击时就会触发这个复合命令及其所有的子命令。
3. 全局使用复合命令CompositeCommand
3.1.使用依赖注入DI来全局使用复合命令 定义接口首先你需要定义一个接口IApplicationCommands该接口包含一个SaveCommand属性它是一个CompositeCommand实例。 public interface IApplicationCommands
{CompositeCommand SaveCommand { get; }
}实现接口然后创建一个类ApplicationCommands来实现这个接口并在类中定义_saveCommand作为CompositeCommand的实例。 public class ApplicationCommands : IApplicationCommands
{private CompositeCommand _saveCommand new CompositeCommand();public CompositeCommand SaveCommand{get _saveCommand;}
}注册为单例在你的应用程序中需要将ApplicationCommands类注册为单例这样在整个应用程序中使用的都是同一个CompositeCommand实例。 public partial class App : PrismApplication
{protected override void RegisterTypes(IContainerRegistry containerRegistry){containerRegistry.RegisterSingletonIApplicationCommands, ApplicationCommands();}
}在ViewModel中注册子命令在ViewModel的构造函数中请求IApplicationCommands接口并使用SaveCommand来注册你的DelegateCommand。 public DelegateCommand UpdateCommand { get; private set; }public TabViewModel(IApplicationCommands applicationCommands)
{UpdateCommand new DelegateCommand(Update);applicationCommands.SaveCommand.RegisterCommand(UpdateCommand);
}3.2.使用静态类来全局使用复合命令 创建静态类创建一个静态类ApplicationCommands并在其中定义一个静态的SaveCommand属性它是一个CompositeCommand实例。 public static class ApplicationCommands
{public static CompositeCommand SaveCommand new CompositeCommand();
}在ViewModel中关联子命令在ViewModel中将你的DelegateCommand与静态的ApplicationCommands类关联起来。 public DelegateCommand UpdateCommand { get; private set; }public TabViewModel()
{UpdateCommand new DelegateCommand(Update);ApplicationCommands.SaveCommand.RegisterCommand(UpdateCommand);
}为了提高代码的可维护性和可测试性推荐使用依赖注入的方式而不是静态类。 4.绑定全局可用的复合命令CompositeCommands
4.1.使用依赖注入Dependency Injection 暴露IApplicationCommands在使用依赖注入DI时你需要在视图模型ViewModel中暴露IApplicationCommands接口以便将其绑定到视图View。 设置属性在视图模型的构造函数中请求IApplicationCommands实例并设置一个类型为IApplicationCommands的属性。 public class MainWindowViewModel : BindableBase
{private IApplicationCommands _applicationCommands;public IApplicationCommands ApplicationCommands{get _applicationCommands;set SetProperty(ref _applicationCommands, value);}public MainWindowViewModel(IApplicationCommands applicationCommands){ApplicationCommands applicationCommands;}
}在这个例子中MainWindowViewModel类有一个ApplicationCommands属性它在构造函数中被设置为传入的IApplicationCommands实例。 在视图中绑定按钮在XAML视图中将按钮的Command属性绑定到ApplicationCommands.SaveCommand属性。SaveCommand是在ApplicationCommands类中定义的。 Button ContentSave Command{Binding ApplicationCommands.SaveCommand}/这里按钮的Command属性被绑定到视图模型中的SaveCommand属性当按钮被点击时会触发SaveCommand。
4.2.使用静态类Static Class 绑定到静态ApplicationCommands类如果你使用的是静态类方法以下代码示例展示了如何在WPF中将按钮绑定到静态的ApplicationCommands类。 Button ContentSave Command{x:Static local:ApplicationCommands.SaveCommand} /在这个例子中按钮的Command属性直接绑定到ApplicationCommands类中的静态SaveCommand属性。
5.从CompositeCommand中注销子命令
在编程中特别是在使用命令模式Command Pattern时我们可能会创建一些命令并将它们注册到一个复合命令CompositeCommand中。这样做的好处是可以将多个命令作为一个单一的命令来处理简化了用户界面UI的操作。
然而当你的视图View或视图模型ViewModel不再需要时比如它们即将被垃圾回收器Garbage Collector, GC回收你应该从CompositeCommand中注销这些子命令。这是因为如果这些子命令仍然被CompositeCommand持有它们将不会被垃圾回收从而导致内存泄漏。内存泄漏是指程序中已分配的内存空间由于某种原因未被正确释放导致随着时间的推移可用内存越来越少最终可能影响程序的性能。 public void Destroy(){_applicationCommands.UnregisterCommand(UpdateCommand);}在这段内容中提供了一个Destroy方法的示例该方法使用CompositeCommand.UnregisterCommand方法来注销一个名为UpdateCommand的子命令。这样做可以确保当View或ViewModel不再需要时相关的命令可以被正确地从CompositeCommand中移除从而允许垃圾回收器回收这些对象避免内存泄漏。
6.执行活跃视图Active Views上的命令
6.1. 在父视图级别协调子视图命令的执行
在某些情况下你可能希望执行所有显示视图上的命令例如前面提到的“保存全部”Save All命令。在其他情况下你可能只希望在当前活跃的视图上执行命令。在这种情况下组合命令CompositeCommand只会在被认为是活跃的视图上执行子命令而不活跃的视图上的子命令则不会执行。例如你可能想在应用程序的工具栏上实现一个“缩放”Zoom命令这个命令只会导致当前活跃的项目被缩放。
6.2. IActiveAware接口
为了支持上述场景Prism提供了IActiveAware接口。该接口定义了一个IsActive属性当实现者处于活跃状态时返回true以及一个IsActiveChanged事件每当活跃状态改变时触发。
6.3. 在视图或视图模型上实现IActiveAware接口
这个接口主要用于跟踪视图的活跃状态。一个视图是否活跃是由特定控件内的视图决定的。例如在Tab控件中有一个适配器将当前选中的标签页中的视图设置为活跃状态。
6.4. DelegateCommand类实现IActiveAware接口
CompositeCommand可以通过在构造函数中指定monitorCommandActivity参数为true来配置以评估子DelegateCommand的活跃状态除了CanExecute状态。当这个参数设置为true时CompositeCommand类在确定CanExecute方法的返回值以及在Execute方法中执行子命令时会考虑每个子DelegateCommand的活跃状态。 public class ApplicationCommands : IApplicationCommands{private CompositeCommand _saveCommand new CompositeCommand(true);public CompositeCommand SaveCommand{get _saveCommand;}}6.5. CompositeCommand的行为
当monitorCommandActivity参数为true时CompositeCommand类表现出以下行为 CanExecute只有在所有活跃的命令都可以执行时才返回true。不活跃的子命令将完全不被考虑。Execute执行所有活跃的命令。不活跃的子命令将完全不被考虑。
6.6. 在ViewModels上实现IActiveAware接口
通过在ViewModels上实现IActiveAware接口当视图变为活跃或不活跃时你将得到通知。当视图的活跃状态改变时你可以更新子命令的活跃状态。然后当用户调用组合命令时活跃子视图上的命令将被调用。
6.7. 示例代码 public class TabViewModel : BindableBase, IActiveAware{private bool _isActive;public bool IsActive{get { return _isActive; }set SetProperty(ref _isActive, OnIsActiveChanged);}public event EventHandler IsActiveChanged;public DelegateCommand UpdateCommand { get; private set; }public TabViewModel(IApplicationCommands applicationCommands){UpdateCommand new DelegateCommand(Update);applicationCommands.SaveCommand.RegisterCommand(UpdateCommand);}private void Update(){//实现逻辑}private void OnIsActiveChanged(){UpdateCommand.IsActive IsActive; //set the command as activeIsActiveChanged?.Invoke(this, new EventArgs()); //invoke the event for all listeners}}提供了一个TabViewModel的示例展示了如何实现IActiveAware接口并在视图的活跃状态改变时更新子命令的活跃状态。
相关链接
介绍Introduction命令Commands 命令Commanding复合命令Composite Commands