Fluent API支持
Fluent APIs利用方法級(jí)聯(lián)傳遞后續(xù)調(diào)用的指令上下文,通過(guò)這樣做,F(xiàn)luent API遵循與人們使用的相同的自然語(yǔ)言規(guī)則。因此,構(gòu)造良好的Fluent API提供了更易于感知和理解的人性化代碼。
要開(kāi)始了解Fluent API概念,請(qǐng)參考以下文章。
一篇由Sacha Barber撰寫(xiě)的Code Project博客文章,描述了什么是Fluent API以及為什么應(yīng)該使用它。
MSDN文檔部分描述了實(shí)體框架范圍內(nèi)的Fluent API。
DevExpress MVVM框架提供了擴(kuò)展方法來(lái)為任何任務(wù)構(gòu)建流暢的API表達(dá)式:從綁定簡(jiǎn)單的屬性到將MVVM行為與特定事件關(guān)聯(lián)起來(lái)。
屬性綁定和UI觸發(fā)器
- 簡(jiǎn)單的屬性綁定。
C#:
mvvmContext.ViewModelType = typeof(ViewModel); var fluentAPI = mvvmContext.OfType<ViewModel>(); fluentAPI.SetBinding(editor, e => e.EditValue, x => x.Title); //ViewModel public virtual string Title { get; set; }
VB.NET:
mvvmContext.ViewModelType = GetType(ViewModel) Dim fluentAPI = mvvmContext.OfType(Of ViewModel)() fluentAPI.SetBinding(editor, Function(e) e.EditValue, Function(x) x.Title) 'ViewModel public virtual String Title {get;set;}
- 綁定到嵌套屬性。
C#:
mvvmContext.ViewModelType = typeof(ViewModel); var fluent = mvvmContext.OfType<ViewModel>(); fluent.SetBinding(editor, e => e.EditValue, x => x.Child.Title); //ViewModel public NestedViewModel Child { get; private set; } //NestedViewModel public virtual string Title { get; set; }
VB.NET:
mvvmContext.ViewModelType = GetType(ViewModel) Dim fluent = mvvmContext.OfType(Of ViewModel)() fluent.SetBinding(editor, Function(e) e.EditValue, Function(x) x.Child.Title) 'ViewModel public NestedViewModel Child {get;private set;} 'NestedViewModel public virtual String Title {get;set;}
- UI 觸發(fā)器。
C#:
mvvmContext.ViewModelType = typeof(UIViewModel); var fluentAPI = mvvmContext.OfType<UIViewModel>(); fluentAPI.SetTrigger(x => x.IsActive, (active) => { label.Text = active ? "Active" : "Inactive"; }); //UIViewModel public virtual bool IsActive { get; set; }
VB.NET:
mvvmContext.ViewModelType = GetType(UIViewModel) Dim fluentAPI = mvvmContext.OfType(Of UIViewModel)() fluentAPI.SetTrigger(Function(x) x.IsActive, Sub(active) label.Text = If(active, "Active", "Inactive")) 'UIViewModel public virtual Boolean IsActive {get;set;}
命令綁定
- 帶有CanExecute條件的參數(shù)化命令。
C#:
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; } }
VB.NET:
mvvmContext.ViewModelType = GetType(ViewModel) Dim parameter As Integer = 4 Dim fluentAPI = mvvmContext.OfType(Of ViewModel)() fluentAPI.BindCommand(commandButton, Function(x, p) x.DoSomething(p), Function(x) parameter) 'ViewModel public class ViewModel public void DoSomething(Integer p) '. . . public Boolean CanDoSomething(Integer p) Return (2 + 2) = p
- 異步命令。
C#:
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; //. . . } }); } }
VB.NET:
mvvmContext.ViewModelType = GetType(ViewModel) Dim fluentAPI = mvvmContext.OfType(Of ViewModel)() fluentAPI.BindCommand(commandButton, Function(x) x.DoSomethingAsynchronously()) fluentAPI.BindCancelCommand(cancelButton, Function(x) x.DoSomethingAsynchronously()) 'ViewModel public class ViewModelWithAsyncCommandAndCancellation public Task DoSomethingAsynchronously() Return Task.Factory.StartNew(Sub() ' cancellation check '. . . Dim asyncCommand = Me.GetAsyncCommand(Function(x) x.DoSomethingAsynchronously()) For i As Integer = 0 To 100 If asyncCommand.IsCancellationRequested Then Exit For End If Next i End Sub) }
- WithCommand擴(kuò)展允許您將命令綁定到一個(gè)或多個(gè)目標(biāo)UI元素。
C#:
//binding to one UI element fluent.WithCommand(x => x.DoSomething()) .Bind(btnDoSomething); //binding to multiple UI elements fluent.WithCommand(x => x.DoSomething()) .Bind(btn1DoSomething) .Bind(btn2DoSomething); fluent.WithCommand(x => x.DoSomethingAsynchronously()) .Bind(btnDo) .BindCancel(btnCancel);
VB.NET:
'binding to one UI element fluent.WithCommand(Function(x) x.DoSomething()). Bind(btnDoSomething) 'binding to multiple UI elements fluent.WithCommand(Function(x) x.DoSomething()) .Bind(btn1DoSomething) .Bind(btn2DoSomething) fluent.WithCommand(Function(x) x.DoSomethingAsynchronously()) .Bind(btnDo) .BindCancel(btnCancel)
- 命令觸發(fā)器允許您在目標(biāo)命令執(zhí)行之前、之后或該命令的CanExecute條件發(fā)生變化時(shí)自動(dòng)調(diào)用特定的方法。
C#:
fluent.WithCommand(x => x.DoSomething()) .After(() => AfterDoSomethingExecuted()); fluent.WithCommand(x => x.DoSomething()) .Before(() => BeforeDoSomethingExecuted()); fluent.WithCommand(x => x.DoSomething()) .OnCanExecuteChanged(() => WhenCanDoSomethingChanged());
VB.NET:
fluent.WithCommand(Function(x) x.DoSomething()) .After(Function() AfterDoSomethingExecuted()) fluent.WithCommand(Function(x) x.DoSomething()) .Before(Function() BeforeDoSomethingExecuted()) fluent.WithCommand(Function(x) x.DoSomething()) .OnCanExecuteChanged(Function() WhenCanDoSomethingChanged())
附加操作
- 確認(rèn)操作 。
C#:
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?"; });
VB.NET:
mvvmContext.WithEvent(Of ChangingEventArgs)(editor, "EditValueChanging").Confirmation(Sub(behavior) behavior.Caption = "CheckEdit State changing" behavior.Text = "This checkEdit's checked-state is about to be changed. Are you sure?" End Sub)
- Event-To-Command操作。
C#:
mvvmContext.ViewModelType = typeof(ViewModel); mvvmContext.WithEvent<ViewModel, EventArgs>(thirdPartyButton, "Click") .EventToCommand(x => x.DoSomething()); //ViewModel public void DoSomething() { //. . . }
VB.NET:
mvvmContext.ViewModelType = GetType(ViewModel) mvvmContext.WithEvent(Of ViewModel, EventArgs)(thirdPartyButton, "Click").EventToCommand(Function(x) x.DoSomething()) 'ViewModel Public Sub DoSomething() '. . . End Sub
- 鍵到命令和鍵到命令操作。
C#:
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);
VB.NET:
mvvmContext.OfType(Of KeyAwareViewModel)().WithKey(memo, Keys.A).KeyToCommand(Function(x) x.OnAKey()) mvvmContext.OfType(Of KeyAwareViewModel)().WithKeys(memo, New Keys() { Keys.A, Keys.B, Keys.C }).KeysToCommand(Function(x) x.OnKey(Keys.None), Function(args) args.KeyCode)