首页 > 其他分享 >PrismMVVM功能实现(通知、命令)

PrismMVVM功能实现(通知、命令)

时间:2023-09-03 15:59:05浏览次数:44  
标签:ArticleViewModel DelegateCommand SubmitCommand 通知 视图 PrismMVVM 命令 public

常见的MVVM框架,基本围绕ICommand、INotifyPropertyChanged的封装实现绑定、通知等功能;而对于不同框架,在实现相同功能上,只是表现的形式有所不同,下图列举几种常见框架的功能区别:

功能\框架 Prism MVVMLight Micorsoft.Tookit.Mvvm
通知 BindableBase ViewModelBase ObservableObject
命令 DelegateCommand RelayCommand Async/RelayCommand 
事件聚合器 IEventAggregator IMessenger IMessenger
模块化 × ×
容器 × ×
依赖注入 × ×
导航 × ×
对话服务 × ×

通知(BindableBase)

BindableBase 主要实现 INotifyPropertyChanged 接口,用于监听属性更改时提供通知,实现方式为在属性 SET 中添加 RaisePropertyChanged() 方法,具体过程如下:

运行效果如下:

单一命令(DelegateCommand)

ViewModel 可以通过将命令接口实现为命令对象 (实现 ICommand 接口的对象)。视图与命令的交互以声明的方式定义,而无需在视图的代码隐藏文件中使用复杂的事件处理代码。实现 ICommand 接口很简单,Prism 提供了 DelegateCommand 此接口的实现,您可以在应用程序中轻松使用。

创建委托命令 

Prism DelegateCommand 类封装了两个委托,每个委托都引用了在 ViewModel 类中实现的方法。它通过调用这些委托来实现 ICommand 接口Execute 和方法。 CanExecute 您在 DelegateCommand 类构造函数中指定 ViewModel 方法的委托。例如,以下代码示例显示了如何DelegateCommand 通过指定 OnSubmit 和 CanSubmit ViewModel 方法的委托来构造表示提交命令的实例。然后,该命令通过一个只读属性暴露给视图,该属性返回对 DelegateCommand . 

//无参、仅Excute构造方式
public class ArticleViewModel
{
    public DelegateCommand SubmitCommand { get; private set; }
    public ArticleViewModel()
    {
    SubmitCommand = new DelegateCommand(Submit);
    }
    void Submit()
    {
        //执行方法
    }
}
//有参、Execute和CanExecut同时构造方式
public class ArticleViewModel
{
    public DelegateCommand SubmitCommand { get; private set; }
    public ArticleViewModel()
    {
    SubmitCommand = new DelegateCommand<object>(Submit, CanSubmit);
    }
    void Submit(object parameter)
    {
    //执行方法
    }
    bool CanSubmit(object parameter)
    {
    return true;
    }
}
//无参、Execute和CanExecut同时构造方式
public class ArticleViewModel
{
    public DelegateCommand SubmitCommand { get; private set; }
    public ArticleViewModel()
    {
    SubmitCommand = new DelegateCommand(Submit, CanSubmit);
    }
    void Submit()
    {
    //implement logic
    }
    bool CanSubmit()
    {
    return true;
    }
}

从视图调用命令

使用 CommandParameter 属性定义命令参数。定义的参数类型在 DelegateCommand 泛型声明中指定。当用户与该控件交互时,该控件将自 动调用目标命令,并且命令参数(如果提供)将作为参数传递给命令的 Execute 方法。 

<Button Command="{Binding SubmitCommand}" CommandParameter="OrderId"/>

创建异步委托命令

在当今的 async / await 使用中,在委托中调用异步方法 Execute 是非常普遍的要求。每个人的第一直觉是他们需要一个 AsyncCommand ,但这种假设是错误的。 ICommand 本质上是同步的, Execute 并且 CanExecute 委托应该被视为事件。这意味着这 async void 是用于命令的完全有效的语法。有两种方法可以将异步方法与 DelegateCommand 结合使用:

方式1 

public class ArticleViewModel
{
    public DelegateCommand SubmitCommand { get; private set; }
    public ArticleViewModel()
    {
    SubmitCommand = new DelegateCommand(Submit);
    }
    async void Submit()
    {
    await SomeAsyncMethod();
    }
}

方式2

public class ArticleViewModel
{
    public DelegateCommand SubmitCommand { get; private set; }
    public ArticleViewModel()
    {
    SubmitCommand = new DelegateCommand(async ()=> await Submit());
    }
    Task Submit()
    {
    return SomeAsyncMethod();
    }
}

复合命令(CompositeCommand) 

在许多情况下,视图模型定义的命令将绑定到关联视图中的控件,以便用户可以直接从视图中调用该命令。但是,在某些情况下,您可能希望能够从应用程序 UI 的父视图中的控件调用一个或多个视图模型上的命令。

Prism 通过 CompositeCommand 类支持这种情况 。

该类 CompositeCommand 表示由多个子命令组成的命令。当调用复合命令时,依次调用它的每个子命令。在您需要将一组命令表示为 UI 中的单个命令或您希望调用多个命令来实现逻辑命令的情况下,它很有用。

该类 CompositeCommand 维护一个子命令( DelegateCommand 实例)列表。类的 Execute 方法 CompositeCommand 简单地依次调用Execute 每个子命令的方法。该 CanExecute 方法类似地调用 CanExecute 每个子命令的方法,但如果任何子命令无法执行,该 CanExecute 方法将返回 false 。也就是说,默认情况下,a CompositeCommand 只有在所有子命令都可以执行时才能执行。

创建复合命令

复合命令绑定到视图

在视图中,将“CompositeButton”按钮与到 TestCompositeCommand 命令绑定。

运行结果如下:

取消注册命令

如前面的示例所示,子命令是使用该 TestCompositeCommand.RegisterCommand 方法注册的。但是,当您不再希望响应 TestCompositeCommand或者您正在销毁 View/ViewModel 以进行垃圾回收时,您应该使用该 TestCompositeCommand.UnregisterCommand 方法取消注册子命令。

/// 取消命令注册例子
public void Destroy()
{
    TestCompositeCommand.UnregisterCommand(TestCommand1);
}

通过依赖注入、静态类来实现 CompositeCommand 全局可用/绑定等用法,请查阅Prism官方文档。

 

标签:ArticleViewModel,DelegateCommand,SubmitCommand,通知,视图,PrismMVVM,命令,public
From: https://www.cnblogs.com/ZHIZRL/p/17675034.html

相关文章

  • kubectl命令
    kubectl的命令可分为三类:1.陈述式命令(命令式对象管理)类似于我们直接在docker中dockerrun命令2.陈述式对象配置(命令式对象配置)类似于类似于docker-compose.yml3.声明式对象配置(声明式对象配置)kubectl命令的语法如下:kubectl[command][type][name][flags]comand:指......
  • linux教程:只用一条命令杀死占用端口为2888的进程
    第一种方式可以使用以下命令来杀死占用端口为2888的进程:kill$(lsof-t-i:2888)上述命令使用了命令替换(commandsubstitution)来获取占用端口为2888的进程的PID,并将其作为参数传递给kill命令。lsof-t-i:2888命令将输出占用该端口的进程的PID列表,kill命令然后将这些PID作为参数来......
  • 导出mysql数据库,导出远程mysql数据库,使用命令行导出mysql数据库
    一篇博客要使用命令行导出MySQL数据库,您可以按照以下步骤进行操作:打开命令提示符或终端窗口,并导航到MySQL的安装目录。以管理员身份运行命令行界面。在Windows操作系统上,可以按下Shift键,然后单击“开始”菜单,输入“cmd”,右键单击“命令提示符”,然后选择“以管理员身份运行”。在M......
  • Linux系统之ifconfig命令的基本使用
    (Linux系统之ifconfig命令的基本使用)一、ifconfig命令介绍1.ifconfig简介ifconfig是Linux中常用的网络配置工具之一,用于配置和显示网络接口的具体状况。2.ifconfig注意事项用ifconfig命令配置的网卡信息,在网卡重启后机器重启后,配置就不存在。要想将上述的配置信息永远的......
  • markdown命令练习
    目录设定关于目录的设定markdown最多允许六级目录,若是想设置一级目录在编辑内容前加一个#即可,(注意:#和要编辑的目录之间需要一个空格的空间,否则可能出现识别不出的情况)若是想要做二级目录,将一个#变成两个即可;若是三级,便是三个#。后面以此类推。注意:用此方法时若不在markdow......
  • linux 防火墙相关命令
    主机名vim/etc/hostnamenode1.itcast.cnnode2.itcast.cnHosts映射vim/etc/hosts192.168.0.140node1node1.itcast.cn192.168.0.141node2node2.itcast.cn192.168.0.130master1192.168.0.140worker1192.168.0.150worker2环境变量vim/etc/profileexportJAVA_HOME=...ex......
  • php:命令行的常用例子(php 8.2.5)
    一,查看安装配置信息[liuhongdi@img~]$/usr/local/soft/php8.2.5/bin/php-i           相当于执行:[liuhongdi@img~]$/usr/local/soft/php8.2.5/bin/php-r"phpinfo();”二,列出开启的扩展模块:[liuhongdi@img~]$/usr/local/soft/php8.2.5/bin/php-m[......
  • 超微IPMICFG使用命令
    命令解释ipmicfg-m显示IPv4地址和MACipmicfg-m<ip>设置IPV4地址ipmicfg-a<mac>设置MACipmicfg-k显示子网掩码ipmicfg-k<mask>设置掩码ipmicfg-dhcp获取DHCP状态ipmicfg-dhcpon启用DHCPipmicfg-d......
  • Crontab命令详解
    Linux系统则是由cron(crond)这个系统服务来控制的。Linux系统上面原本就有非常多的计划性工作,因此这个系统服务是默认启动的。另外,由于使用者自己也可以设置计划任务,所以,Linux系统也提供了使用者控制计划任务的命令:crontab命令。一、crond简介crond 是linux下用来周期......
  • 视图开发 命令式 声明式 将视图和数据分离
    10|Widget中的State到底是什么?https://time.geekbang.org/column/article/108576 下述代码分别展示了在Android、iOS及原生Javascript中,如何将一个文本控件的展示文案更改为HelloWorld://Android设置某文本控件展示文案为HelloWorldTextViewtextView=(TextView)f......