03_Prism_命令

Prism 提供了 DelegateCommand 类来实现命令。界面中的UI控件与命令之间的交互可以是双向的,可以启用或禁用底层命令时自动启用或禁用UI。

DelegateCommand

// DelegateCommand.cs
public class DelegateCommand<T> : DelegateCommandBase
{
    public DelegateCommand(Action<T> executeMethod,Func<T,bool> canExecuteMethod ): base((o) => executeMethod((T)o), (o) => canExecuteMethod((T)o))
    {
        ...
    }
}

View调用 DelegateCommand

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

控件状态变更通知

ViewModel 通常需要指示命令 CanExecute 状态的变更,一边UI控件更新是否可用状态。

RaisCanExecuteChanged

当需要手动更新绑定的 UI 元素的状态时,调用 RaisCanExecuteChanged 方法。

private bool _isEnabled;
public bool IsEnabled
{
    get { return _isEnabled; }
    set
    {
        SetProperty(ref _isEnabled, value);
        SubmitCommand.RaiseCanExecuteChanged();
    }
}
ObservesProperty

观察属性值的变化,当属性值改变时自动调用 RaisCanExecuteChanged 方法来通知 UI 状态变化。

public class ArticleViewModel : BindableBase
{
    private bool _isEnabled;
    public bool IsEnabled
    {
        get { return _isEnabled; }
        set { SetProperty(ref _isEnabled, value); }
    }

    public DelegateCommand SubmitCommand { get; private set; }

    public ArticleViewModel()
    {
        SubmitCommand = new DelegateCommand(Submit, CanSubmit).ObservesProperty(() => IsEnabled);
    }

    void Submit()
    {
        //implement logic
    }

    bool CanSubmit()
    {
        return IsEnabled;
    }
}

使用 ObservesProperty 方法时,可以同时观察多个属性。ObservesProperty(() => IsEnabled).ObservesProperty(() => CanSave)

ObservesCanExecute
public class ArticleViewModel : BindableBase
{
    private bool _isEnabled;
    public bool IsEnabled
    {
        get { return _isEnabled; }
        set { SetProperty(ref _isEnabled, value); }
    }

    public DelegateCommand SubmitCommand { get; private set; }

    public ArticleViewModel()
    {
        SubmitCommand = new DelegateCommand(Submit).ObservesCanExecute(() => IsEnabled);
    }

    void Submit()
    {
        //implement logic
    }
}

异步任务

有时候会需要异步执行 Execute 方法,此时会想到一个 AsyncCommand ,但ICommand 本质上是同步的,所以 AsyncCommand 这种是错误的。

Execute 和 CanExecute 委托事件可以使用 async void 进行修饰。

// 方法一
public class ArticleViewModel
{
    public DelegateCommand SubmitCommand { get; private set; }

    public ArticleViewModel()
    {
        SubmitCommand = new DelegateCommand(Submit);
    }

    async void Submit()
    {
        await SomeAsyncMethod();
    }
}

// 方法二
public class ArticleViewModel
{
    public DelegateCommand SubmitCommand { get; private set; }

    public ArticleViewModel()
    {
        SubmitCommand = new DelegateCommand(async ()=> await Submit());
    }

    Task Submit()
    {
        return SomeAsyncMethod();
    }
}

复合命令

有时候,希望程序能够一次性调用多个命令。复合命令 CompositeCommand 表示由多个子命令组成的命令。

在这里插入图片描述

// 创建一个复合命令
public class ApplicationCommands
{
    private CompositeCommand _saveCommand = new CompositeCommand();
    public CompositeCommand SaveCommand
    {
        get { return _saveCommand; }
    }
}

通常,CompositeCommands 在整个应用程序中共享,并且需要全局可用。可以通过依赖注入或静态类来定义 CompositeCommands为单例。建议使用依赖注入的方法。

依赖注入
// 创建一个接口
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>();
    }
}

现在可以在ViewModel中注册子命令到复合命令了。

// 复合命令,用于绑定到UI
private IApplicationCommands _applicationCommands;
public IApplicationCommands ApplicationCommands
{
    get { return _applicationCommands; }
    set { SetProperty(ref _applicationCommands, value); }
}

// 子命令
public DelegateCommand UpdateCommand { get; private set; }

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

绑定到UI元素

<Button Content="Save" Command="{Binding ApplicationCommands.SaveCommand}"/>
使用静态类
public static class ApplicationCommands
{
    public static CompositeCommand SaveCommand = new CompositeCommand();
}

在 ViewModel 中,将子命令关联到静态 ApplicationCommands 类。

public DelegateCommand UpdateCommand { get; private set; }

public TabViewModel()
{
    UpdateCommand = new DelegateCommand(Update);
    ApplicationCommands.SaveCommand.RegisterCommand(UpdateCommand);
}

绑定到UI元素

<Button Content="Save" Command="{x:Static local:ApplicationCommands.SaveCommand}" />
我的公众号 HelloPragram

在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值