9.【DevExpress MVVM】Fluent API支持

100 阅读2分钟

Fluent API利用方法级联来连接后续调用的指令上下文。通过这样做,Fluent API遵循与人们使用的自然语言规则相同的自然语言规则。因此,构造良好的Fluent API提供了更人性化的代码,更容易理解和理解。

提示:
要想着手了解Fluent API概念,请参阅以下文章。
看一看Fluent api
由Sacha Barber写的一篇代码项目博客文章,描述了什么是Fluent API以及为什么你应该使用它。
第一行Fluent API代码
MSDN文档里的一章,它描述了Entity Framework范围内的Fluent API。

DevExpress MVVM框架提供了扩展方法来为任何任务构建连贯的API表达式:从绑定简单的属性到将MVVM行为与特定事件关联。

属性绑定和UI触发器

  • 一个简单的属性绑定
mvvmContext.ViewModelType = typeof(ViewModel);
var fluentAPI = mvvmContext.OfType<ViewModel>();
fluentAPI.SetBinding(editor, e => e.EditValue, x => x.Title);
//ViewModel.cs
public virtual string Title { get; set; }
  • 绑定到内部属性
mvvmContext.ViewModelType = typeof(ViewModel);
var fluent = mvvmContext.OfType<ViewModel>();
fluent.SetBinding(editor, e => e.EditValue, x => x.Child.Title);
//ViewModel.cs
public NestedViewModel Child { get; private set; }
//NestedViewModel.cs
public virtual string Title { get; set; }
  • UI触发器
mvvmContext.ViewModelType = typeof(UIViewModel);
var fluentAPI = mvvmContext.OfType<UIViewModel>();
fluentAPI.SetTrigger(x => x.IsActive, (active) =>
{
    label.Text = active ? "Active" : "Inactive";
});
//UIViewModel.cs
public virtual bool IsActive { get; set; }

命令绑定

  • 带有CanExecute条件的参数化命令
mvvmContext.ViewModelType = typeof(ViewModel);
int parameter = 4;
var fluentAPI = mvvmContext.OfType<ViewModel>();
fluentAPI.BindCommand(commandButton, (x, p) => x.DoSomething(p), x => parameter);

//ViewModel
public class ViewModel {
    public void DoSomething(int p) {
        //. . .
    }

    public bool CanDoSomething(int p) {
        return (2 + 2) == p;
    }
}
  • 异步命令
mvvmContext.ViewModelType = typeof(ViewModel);
var fluentAPI = mvvmContext.OfType<ViewModel>();
fluentAPI.BindCommand(commandButton, x => x.DoSomethingAsynchronously());
fluentAPI.BindCancelCommand(cancelButton, x => x.DoSomethingAsynchronously());

//ViewModel
public class ViewModelWithAsyncCommandAndCancellation 
    public Task DoSomethingAsynchronously() {
        return Task.Factory.StartNew(() =>
        {
            var asyncCommand = this.GetAsyncCommand(x => x.DoSomethingAsynchronously());
            for(int i = 0; i <= 100; i++) {
                if(asyncCommand.IsCancellationRequested) // cancellation check
                    break;
                //. . .
            }
        });
    }
}
  • WithCommand扩展允许您将命令绑定到一个或多个目标UI元素
//绑定到一个UI元素
fluent.WithCommand(x => x.DoSomething())
       .Bind(btnDoSomething);
//绑定到多个UI元素
fluent.WithCommand(x => x.DoSomething())
       .Bind(btn1DoSomething)
       .Bind(btn2DoSomething);
fluent.WithCommand(x => x.DoSomethingAsynchronously())
       .Bind(btnDo)
       .BindCancel(btnCancel);
  • 命令触发器允许您在执行目标命令之前、之后或当该命令的CanExecute条件更改时自动调用特定的方法
fluent.WithCommand(x => x.DoSomething())
       .After(() => AfterDoSomethingExecuted());
fluent.WithCommand(x => x.DoSomething())
       .Before(() => BeforeDoSomethingExecuted());
fluent.WithCommand(x => x.DoSomething())
       .OnCanExecuteChanged(() => WhenCanDoSomethingChanged());

绑上行为

  • 确认行为
mvvmContext.WithEvent<ChangingEventArgs>(editor, "EditValueChanging")
    .Confirmation(behavior =>
    {
        behavior.Caption = "CheckEdit State changing";
        behavior.Text = "This checkEdit's checked-state is about to be changed. Are you sure?";
    });
  • Event-To-Command行为
mvvmContext.ViewModelType = typeof(ViewModel);
mvvmContext.WithEvent<ViewModel, EventArgs>(thirdPartyButton, "Click")
    .EventToCommand(x => x.DoSomething());

//ViewModel
public void DoSomething() {
    //. . .
}
  • Key-To-Command和Keys-To-Command行为
mvvmContext.OfType<KeyAwareViewModel>()
        .WithKey(memo, Keys.A)
        .KeyToCommand(x => x.OnAKey());
mvvmContext.OfType<KeyAwareViewModel>()
        .WithKeys(memo, new Keys[] { Keys.A, Keys.B, Keys.C })
        .KeysToCommand(x => x.OnKey(Keys.None), args => args.KeyCode);

【DevExpress MVVM】中文翻译系列.文章目录

DevExpress.WindowsForms.v20.1.chm离线英文原版文档下载