• Prism 4.复合命令


    Prism 4.复合命令

    常规:一个ViewModel提供一个Command,绑定到一个View中去

    但是,有时会有这样的情况:在一个父控件中,需要触发他的多个子控件的命令。

    (感觉,类似,路由事件。。。)

    CompositeCommand

    这里面维护了一组子命令,当这个复合命令触发时,里面的一组子命令都会执行

    如果所有子命令都可以执行的话才会触发(CanExcute==true),如果可以触发每个命令会触发自己的Excute方法

    创建CompositeCommand命令

            private CompositeCommand _saveCommand = new CompositeCommand();
            public CompositeCommand SaveCommand
            {
                get { return _saveCommand; }
            }
    

    CompositeCommand需要全局使用,一般通过DI定义为单例,或者用static实现

    1.DI生成,定义为单例
     public interface IApplicationCommands
        {
            CompositeCommand SaveCommand { get; }
       }
    
     public class ApplicationCommands : IApplicationCommands
        {
            private CompositeCommand _saveCommand = new CompositeCommand();
            public CompositeCommand SaveCommand
            {
                get { return _saveCommand; }
            }
        }
    
     public partial class App : PrismApplication
        {
            protected override void RegisterTypes(IContainerRegistry containerRegistry)
            {
                containerRegistry.RegisterSingleton<IApplicationCommands, ApplicationCommands>();
            }
        }
    

    已经注册为单例模式,下一步将子command注册到复合命令

    public DelegateCommand UpdateCommand { get; private set; }
    
        public TabViewModel(IApplicationCommands applicationCommands)
        {
            UpdateCommand = new DelegateCommand(Update);
            applicationCommands.SaveCommand.RegisterCommand(UpdateCommand);
        }
    

    2.static生成

    public static class ApplicationCommands
    {
        public static CompositeCommand SaveCommand = new CompositeCommand();
    }
    
     public DelegateCommand UpdateCommand { get; private set; }
    
        public TabViewModel()
        {
            UpdateCommand = new DelegateCommand(Update);
            ApplicationCommands.SaveCommand.RegisterCommand(UpdateCommand);
        }
    

    提示:为了保持代码的可维护性和测试性,建议用DI生成的方式哦

    绑定CompositeCommand到UI

    用DI的方式

    ViewModel,首先你得暴露出一个CompositeCommand的属性,然后在构造函数中传入CompositeCommand实例

      public class MainWindowViewModel : BindableBase
        {
            private IApplicationCommands _applicationCommands;
            public IApplicationCommands ApplicationCommands
            {
                get { return _applicationCommands; }
                set { SetProperty(ref _applicationCommands, value); }
            }
    
            public MainWindowViewModel(IApplicationCommands applicationCommands)
            {
                ApplicationCommands = applicationCommands;
            }
        }
    

    View

    <Button Content="Save" Command="{Binding ApplicationCommands.SaveCommand}"/>
    
    用Static的方式

    View直接绑定

    <Button Content="Save" Command="{x:Static local:ApplicationCommands.SaveCommand}" />
    

    如何减少子类命令比如

    如果遇到了比如你想回收View/Viewmodel的情况,你得取消注册命令

      public void Destroy()
        {
            _applicationCommands.UnregisterCommand(UpdateCommand);
        }
    

    警告:当你不需要View/Viewmodel的时候,你必须解除注册CompositeCommand,否则会导致内存泄漏

    只在活动窗口去执行命令

    情形:父控件点击,只有激活窗口才响应命令

     private CompositeCommand _saveCommand = new CompositeCommand(true);
    

    这个true的意思:

    1 CanExecute,当所有激活的子控件的CanExecute==true,才为true,不考虑没有激活的控件

    2 只执行激活的控件的命令.Excute

    如何通知子控件的激活状态,实现IActiveAware接口
      public class TabViewModel : BindableBase, IActiveAware
        {
            private bool _isActive;
            public bool IsActive
            {
                get { return _isActive; }
                set
                {
                    _isActive = value;
                    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()
            {
                //implement logic
            }
    
            private void OnIsActiveChanged()
            {
                UpdateCommand.IsActive = IsActive; //set the command as active
                IsActiveChanged?.Invoke(this, new EventArgs()); //invoke the event for all listeners
            }
        }
    
  • 相关阅读:
    华硕路由器修改 Hosts 以达到局域网内自定义解析
    一款开源、高颜值的终端terminus,支持Windows、MacOS
    Windows 10启用Linux子系统(WSL)
    一款全能的下载工具Motrix,支持BT、磁力链、百度网盘等资源
    ubuntu 14.04 和16.04 快速下载
    CentOS 7一键安装Seafile搭建私有云存储
    background背景色
    3d爱心代码
    Mac Mini(late 2014) 添加NVMe固态组Fusion Drive
    member access within misaligned address 0x0000002c3931 for type 'struct ListNode‘
  • 原文地址:https://www.cnblogs.com/swobble/p/12809961.html
Copyright © 2020-2023  润新知