zoukankan      html  css  js  c++  java
  • 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
            }
        }
    
  • 相关阅读:
    二叉树专题
    强化学习的几个基本概念
    LeetCode #111 二叉树的最小深度
    NC127 最长公共子串
    快速排序
    NC78 反转链表
    《合作的进化》读后总结
    Optional和Stream的map与flatMap
    最爱的小工具,谁用谁知道!
    SpringBoot应用启动过程分析
  • 原文地址:https://www.cnblogs.com/swobble/p/12809961.html
Copyright © 2011-2022 走看看