Commanding

除了提供对要在视图中显示或编辑的数据的访问之外,ViewModel还可能定义可由用户执行的一个或多个动作或操作。用户可以通过UI执行的动作或操作通常被定义为命令。命令提供了一种方便的方法来表示可以轻松绑定到UI中的控件的操作或操作。它们封装了实现操作或操作的实际代码,并有助于使其与视图中的实际可视化表示分离。

当用户与视图交互时,用户可以以多种不同的方式直观地表示和调用命令。在大多数情况下,它们是通过鼠标单击调用的,但也可以通过快捷键按下,触摸手势或任何其他输入事件来调用它们。视图中的控件是绑定到ViewModel命令的数据,以便用户可以使用控件定义的任何输入事件或手势来调用它们。视图中的UI控件与命令之间的交互可以是双向的。在这种情况下,可以在用户与UI交互时调用该命令,并且可以在启用或禁用基础命令时自动启用或禁用UI。

ViewModel可以将命令实现为命令对象(实现ICommand接口的对象)。可以以声明方式定义视图与命令的交互,而无需在视图的代码隐藏文件中使用复杂的事件处理代码。例如,某些控件固有地支持命令并提供Command可以是绑定到ICommandViewModel提供的对象的数据的属性。在其他情况下,命令行为可用于将控件与ViewModel提供的命令方法或命令对象相关联。

实现ICommand界面很简单。Prism提供了DelegateCommand这个界面的实现,您可以在应用程序中轻松使用它。

Using Delegate Commands视频教程

DelegateCommand

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

public class ArticleViewModel
{public DelegateCommand SubmitCommand { get; private set; }public ArticleViewModel(){SubmitCommand = new DelegateCommand<object>(Submit, CanSubmit);}void Submit(object parameter){//implement logic}bool CanSubmit(object parameter){return true;}
}

DelegateCommand对象上调用Execute方法时,它只是通过您在构造函数中指定的委托将调用转发到ViewModel类中的方法。同样,CanExecute调用该方法时,将调用ViewModel类中的相应方法。CanExecute构造函数中方法的委托是可选的。如果没有指定一个委托,DelegateCommand将始终返回trueCanExecute

DelegateCommand班是一个泛型类型。type参数指定传递给ExecuteCanExecute方法的命令参数的类型。在前面的示例中,command参数是type object非通用的版本DelegateCommand类也通过棱镜用于提供当没有所需的命令参数,并且被定义为如下:

public class ArticleViewModel
{public DelegateCommand SubmitCommand { get; private set; }public ArticleViewModel(){SubmitCommand = new DelegateCommand(Submit, CanSubmit);}void Submit(){//implement logic}bool CanSubmit(){return true;}
}

所述DelegateCommand故意阻止使用值类型(int,双,布尔等)。因为ICommand需要一个object具有值类型T将导致当意外行为CanExecute(null)XAML初始化命令绑定期间被调用。使用default(T)被认为是被拒绝作为解决方案,因为实现者无法区分有效值和默认值。如果要将值类型用作参数,则必须使用DelegateCommand<Nullable<int>>或使用简写?语法(DelegateCommand<int?>)使其可为空。

从View调用DelegateCommands

有许多方法可以将视图中的控件与ViewModel提供的命令对象相关联。某些WPF,Xamarin.Forms和UWP控件可以通过Command属性轻松地绑定到命令对象。

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

也可以使用CommandParameter属性选择性地定义命令参数。期望参数的类型在DelegateCommand<T>泛型声明中指定。当用户与该控件交互时,控件将自动调用目标命令,并且命令参数(如果提供)将作为参数传递给命令的Execute方法。在前面的示例中,按钮将SubmitCommand在单击时自动调用。此外,如果CanExecute指定了委托,则CanExecute返回时将自动禁用该按钮,如果返回false则将启用该按钮true

Raising Change Notifications

ViewModel通常需要指示命令CanExecute状态的更改,以便UI中绑定到该命令的任何控件都将更新其启用状态以反映绑定命令的可用性。在DelegateCommand提供了几种这些通知发送到用户界面。

RaiseCanExecuteChanged

RaiseCanExecuteChanged每当需要手动更新绑定的UI元素的状态时,请使用该方法。例如,当IsEnabled属性值更改时,我们调用RaiseCanExecuteChanged属性的setter来通知UI状态更改。

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

ObservesProperty

如果命令应在属性值更改时发送通知,则可以使用该ObservesProperty方法。使用该ObservesProperty方法时,只要提供的属性的值发生更改,DelegateCommand将自动调用RaiseCanExecuteChanged以通知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

如果您CanExecute是简单Boolean属性的结果,则可以省去声明CanExecute委托,并使用该ObservesCanExecute方法。ObservesCanExecute当注册的属性值发生变化时,它不仅会向UI发送通知,而且还会使用与实际CanExecute委托相同的属性。

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).ObservesCanExecute(() => IsEnabled);}void Submit(){//implement logic}
}
警告

不要尝试链式注册ObservesCanExecute方法。CanExcute代表只能观察到一个属性。

基于Task-Based的DelegateCommand

async/await调用Execute委托内部的异步方法是一个非常常见的要求。每个人的第一直觉是他们需要一个AsyncCommand,但这种假设是错误的。ICommand本质上是同步的,并且代表ExecuteCanExecute代表应被视为事件。这意味着这async void是一个非常有效的语法用于命令。使用异步方法有两种方法DelegateCommand

  • 方法一
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();}
}

转载于:https://www.cnblogs.com/lovexinyi/p/11068914.html

Prism_Commanding(2)相关推荐

最新文章

  1. Android WiFi开发教程(三)——WiFi热点数据传输
  2. jenkins和docker实现自动化构建部署
  3. python书籍_Python 之父宣布加盟微软!包邮送几本 Python 书籍压压惊!
  4. LeetCode之283. Move Zeroes
  5. https证书pfx 生成 pem,crt,key
  6. 怎样获取UIWebView 的文字的高度
  7. Python代码分析工具:PyChecker、Pylint
  8. 解决ubuntu的firefox上网速度慢[转]
  9. 程序员必须掌握的十大经典算法
  10. K近邻算法(K-NN)
  11. halcon之屌炸天的自标定
  12. 怎么恢复格式化的sd卡呢?
  13. 中国互联网公司最新市值排名(2012.12.06)
  14. 求营业额占比 【问题描述】 从键盘输入学校附近某烧烤店某年每月的营业额,然后计算每月的营业额在年营业额中所占的百分比(四舍五入为整数,且不会超过全年的70%),并以样例输出所示的水平直方图形式
  15. 乳腺数据DDSM标注overlay文件python处理
  16. BZOJ 4031 HEOI2015 小Z的房间 Matrix-Tree定理
  17. Python爬虫获取企查查公开的企业信息
  18. Linux操作系统的发展
  19. Python中的range函数和arange函数的区别与联系
  20. 华硕天选无法识别蓝牙

热门文章

  1. 在美国纽约哪里有西联汇款?本文提供美国纽约法拉盛西联汇款网点代理地址
  2. 2015-10-17
  3. HTML5期末大作业:电影网站设计——电影资讯博客(5页) HTML+CSS+JavaScript 学生DW网页设计作业成品 web课程设计网页规划与设计 web学生网页设计作业源码
  4. 【Matlab】基于皮肤概率建模的人脸检测算法雏形
  5. 『英语杂谈』 [好文共赏]Heal the World(转载)
  6. 【Benewake(北醒) 】中距 TF02-i 40m工业版本CAN/485介绍以及资料整理
  7. 不给移动一分钱!10个免费发短信的国外站点
  8. 深度学习词汇表(一)
  9. 使用Qt通过Post发送Json格式数据
  10. 计算机硬盘读取超慢,如何解决电脑硬盘速度慢