Skip to main content

DevExpress v24.2 Update — Your Feedback Matters

Our What's New in v24.2 webpage includes product-specific surveys. Your response to our survey questions will help us measure product satisfaction for features released in this major update and help us refine our plans for our next major release.

Take the survey Not interested

Fluent API Support

  • 4 minutes to read

Fluent APIs utilize method cascading to relay the instruction context of a subsequent call. By doing so, a Fluent API follows the same natural language rules as those utilized by people. As a result, a well-constructed Fluent API provides more human-friendly code that is easier to perceive and understand.

Tip

To get started with Fluent API concepts, refer to the following article: Code First Fluent API.

The DevExpress MVVM Framework provides extension methods to build Fluent API expressions for any task: from binding simple properties to relating MVVM behaviors with specific events.

#Property Binding and UI Triggers

Related article: Data Bindings and Notifications

  • Simple property binding.

    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; }
    
  • Binding to nested properties.

    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; }
    
  • UI Triggers.

    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; }
    

#Command Binding

Related article: Commands

  • Parameterized commands with CanExecute conditions.

    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;
        }
    }
    
  • Asynchronous commands.

    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;
                    //. . .
                }
            });
        }
    }
    
  • The WithCommand extension allows you to bind a command to one or multiple target UI elements.

    //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);
    
  • Command triggers allow you to automatically call specific methods before the target command is executed, after that, or when this command’s CanExecute condition changes.

    fluent.WithCommand(x => x.DoSomething())
           .After(() => AfterDoSomethingExecuted());
    fluent.WithCommand(x => x.DoSomething())
           .Before(() => BeforeDoSomethingExecuted());
    fluent.WithCommand(x => x.DoSomething())
           .OnCanExecuteChanged(() => WhenCanDoSomethingChanged());
    

#Attaching Behaviors

Related article: Behaviors

  • Confirmation behavior.

    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 Behaviors

    mvvmContext.ViewModelType = typeof(ViewModel);
    mvvmContext.WithEvent<ViewModel, EventArgs>(thirdPartyButton, "Click")
        .EventToCommand(x => x.DoSomething());
    
    //ViewModel
    public void DoSomething() {
        //. . .
    }
    
  • Key-To-Command and Keys-To-Command Behaviors

    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);