界面控件DevExpress WinForm - MVVM命令讲解(二)
获取工具下载 - DevExpress WinForm v21.2
带参数的命令
DevExpress MVVM框架接受public void方法的一个参数作为参数化命令,您可以使用此参数在 View 和 ViewModel 之间传递数据。
C#
//ViewModel public class ViewModelWithParametrizedCommand { public void DoSomething(object p) { var msgBoxService = this.GetService<IMessageBoxService>(); msgBoxService.ShowMessage(string.Format("The parameter is {0}.", p)); } } //View mvvmContext.ViewModelType = typeof(ViewModelWithParametrizedCommand); var fluent = mvvmContext.OfType<ViewModelWithParametrizedCommand>(); object parameter = 5; fluent.BindCommand(commandButton, x => x.DoSomething, x => parameter);
VB.NET
'ViewModel Public Class ViewModelWithParametrizedCommand Public Sub DoSomething(ByVal p As Object) Dim msgBoxService = Me.GetService(Of IMessageBoxService)() msgBoxService.ShowMessage(String.Format("The parameter is {0}.", p)) End Sub End Class 'View mvvmContext.ViewModelType = GetType(ViewModelWithParametrizedCommand) Dim fluent = mvvmContext.OfType(Of ViewModelWithParametrizedCommand)() Dim parameter As Object = 5 fluent.BindCommand(commandButton, Sub(x) x.DoSomething(Nothing), Function(x) parameter)
您还可以向 CanExecute 条件添加参数。
C#
//ViewModel public class ViewModelWithParametrizedConditionalCommand { public void DoSomething(int p) { var msgBoxService = this.GetService<IMessageBoxService>(); msgBoxService.ShowMessage(string.Format( "The parameter is {0}.", p)); } public bool CanDoSomething(int p) { return (2 + 2) == p; } } //View mvvmContext.ViewModelType = typeof(ViewModelWithParametrizedConditionalCommand); var fluent = mvvmContext.OfType<ViewModelWithParametrizedConditionalCommand>(); int parameter = 4; fluent.BindCommand(commandButton, x => x.DoSomething, x => parameter);
VB.NET
'ViewModel Public Class ViewModelWithParametrizedConditionalCommand Public Sub DoSomething(ByVal p As Integer) Dim msgBoxService = Me.GetService(Of IMessageBoxService)() msgBoxService.ShowMessage(String.Format("The parameter is {0}.", p)) End Sub Public Function CanDoSomething(ByVal p As Integer) As Boolean Return (2 + 2) = p End Function End Class 'View mvvmContext.ViewModelType = GetType(ViewModelWithParametrizedConditionalCommand) Dim fluent = mvvmContext.OfType(Of ViewModelWithParametrizedConditionalCommand)() Dim parameter As Integer = 4 fluent.BindCommand(commandButton, Sub(x) x.DoSomething(Nothing), Function(x) parameter)
异步命令
如果需要执行延迟或连续操作,请使用异步命令。 要创建异步命令,请声明 System.Threading.Tasks.Task 类型的公共方法(您可以使用 async/await 语法),将 UI 元素绑定到命令的代码保持不变,框架在命令运行时禁用此元素。
C#
//ViewModel public class ViewModelWithAsyncCommand { public async Task DoSomethingAsync() { // do some work here await Task.Delay(1000); } } //View mvvmContext.ViewModelType = typeof(ViewModelWithAsyncCommand); var fluent = mvvmContext.OfType<ViewModelWithAsyncCommand>(); fluent.BindCommand(commandButton, x => x.DoSomethingAsync);
VB.NET
'ViewModel Public Class ViewModelWithAsyncCommand Public Async Sub DoSomethingAsync() As Task ' do some work here Await Task.Delay(1000) End Sub End Class 'View mvvmContext.ViewModelType = GetType(ViewModelWithAsyncCommand) Dim fluent = mvvmContext.OfType(Of ViewModelWithAsyncCommand)() fluent.BindCommand(commandButton, Sub(x) x.DoSomethingAsync(Nothing))
任务支持取消标记,允许您检查 IsCancellationRequested 属性并在此属性返回 true 时中止任务。 如果将此代码添加到异步命令中,请使用 BindCancelCommand 方法创建停止正在进行的异步命令的 UI 元素。 DevExpress MVVM 框架锁定了这个取消按钮,并且只有在相关的异步命令正在运行时才启用它。
C#
//ViewModel public class ViewModelWithAsyncCommandAndCancellation { public async Task DoSomethingAsynchronously() { var dispatcher = this.GetService<IDispatcherService>(); var asyncCommand = this.GetAsyncCommand(x => x.DoSomethingAsynchronously()); for(int i = 0; i <= 100; i++) { if(asyncCommand.IsCancellationRequested) break; // do some work here await Task.Delay(25); await UpdateProgressOnUIThread(dispatcher, i); } await UpdateProgressOnUIThread(dispatcher, 0); } public int Progress { get; private set; } //update the "Progress" property bound to the progress bar within a View async Task UpdateProgressOnUIThread(IDispatcherService dispatcher, int progress) { await dispatcher.BeginInvoke(() => { Progress = progress; this.RaisePropertyChanged(x => x.Progress); }); } } //View mvvmContext.ViewModelType = typeof(ViewModelWithAsyncCommandAndCancellation); var fluent = mvvmContext.OfType<ViewModelWithAsyncCommandAndCancellation>(); fluent.BindCommand(commandButton, x => x.DoSomethingAsynchronously); fluent.BindCancelCommand(cancelButton, x => x.DoSomethingAsynchronously); fluent.SetBinding(progressBar, p => p.EditValue, x => x.Progress);
VB.NET
'ViewModel Public Class ViewModelWithAsyncCommandAndCancellation Public Async Sub DoSomethingAsynchronously() As Task Dim dispatcher = Me.GetService(Of IDispatcherService)() Dim asyncCommand = Me.GetAsyncCommand(Sub(x) x.DoSomethingAsynchronously()) For i As Integer = 0 To 100 If asyncCommand.IsCancellationRequested Then Exit For End If ' do some work here Await Task.Delay(25) Await UpdateProgressOnUIThread(dispatcher, i) Next i Await UpdateProgressOnUIThread(dispatcher, 0) End Sub Private privateProgress As Integer Public Property Progress() As Integer Get Return privateProgress End Get Private Set(ByVal value As Integer) privateProgress = value End Set End Property 'update the "Progress" property bound to the progress bar within a View Private Async Sub UpdateProgressOnUIThread(ByVal dispatcher As IDispatcherService, ByVal progress As Integer) As Task Await dispatcher.BeginInvoke(Sub() Me.Progress = progress Me.RaisePropertyChanged(Sub(x) x.Progress) End Sub) End Sub End Class 'View mvvmContext.ViewModelType = GetType(ViewModelWithAsyncCommandAndCancellation) Dim fluent = mvvmContext.OfType(Of ViewModelWithAsyncCommandAndCancellation)() fluent.BindCommand(commandButton, Sub(x) x.DoSomethingAsynchronously) fluent.BindCancelCommand(cancelButton, Sub(x) x.DoSomethingAsynchronously) fluent.SetBinding(progressBar, Sub(p) p.EditValue, Sub(x) x.Progress)
WithCommand Fluent API 方法还支持可取消的异步命令。
C#
mvvmContext.ViewModelType = typeof(ViewModelWithAsyncCommandAndCancellation); // Initialize the Fluent API var fluent = mvvmContext.OfType<ViewModelWithAsyncCommandAndCancellation>(); // Binding for buttons fluent.WithCommand(x => x.DoSomethingAsynchronously) .Bind(commandButton) .BindCancel(cancelButton);
VB.NET
mvvmContext.ViewModelType = GetType(ViewModelWithAsyncCommandAndCancellation) ' Initialize the Fluent API Dim fluent = mvvmContext.OfType(Of ViewModelWithAsyncCommandAndCancellation)() ' Binding for buttons fluent.WithCommand(Sub(x) x.DoSomethingAsynchronously).Bind(commandButton).BindCancel(cancelButton)
DevExpress WinForm拥有180+组件和UI库,能为Windows Forms平台创建具有影响力的业务解决方案。DevExpress WinForms能完美构建流畅、美观且易于使用的应用程序,无论是Office风格的界面,还是分析处理大批量的业务数据,它都能轻松胜任!
DevExpress技术交流群5:742234706 欢迎一起进群讨论
更多DevExpress线上公开课、中文教程资讯请上中文网获取
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
2020-12-08 WPF应用界面能轻松自定义外观,2021这款工具必不可少
2017-12-08 DevExpress v17.2—WPF篇(一)