Skip to content

ViewModel with async Command #4965

Closed
Closed

Description

@itg-assistant

Alex Prinias asked 2026-04-19 10:24:50 UTC

Hi guys,

If I have a ViewModel with an async method, how can I define a Command to bind to a button in my View?
The problem I see is that when I click the Login button, I am not navigated from my login View to my main view, but if I click somewhere on the page, then the navigation happens indeed. If I remove async from the method, this works from the first click.
I am reading in the docs about Application.Update(this), but I don't think it is reasonable to call Application.Update(this) from the ViewModel, what "this" should be in that case?

Is this even possible, or am I trying in vain?

Best regards,
Alex

For example, I have a LoginViewModel with the following method.

private async Task LoginAsync()

    {

        try

        {

            IsBusy = true;

            ErrorMessage = string.Empty;

            var success = await _authService.LoginAsync(Username, Password);

            if (!success)

                ErrorMessage = "Invalid username or password.";

            // If success, AuthenticationService will raise event and ApplicationViewModel will handle shell swap

        }

        catch (Exception ex)

        {

            ErrorMessage = $"Login failed: {ex.Message}";

        }

        finally

        {

            IsBusy = false;

        }

    }

And I am trying to define my command in the constructor:

public LoginViewModel(IAuthenticationService authService)

    {

        _authService = authService;

        LoginCommand = new Command(

            execute: async () => { await LoginAsync(); },

            canExecute: () => !IsBusy && !string.IsNullOrWhiteSpace(Username) && !string.IsNullOrWhiteSpace(Password));

    }

and in my LoginView:

btnLogin.Command = _vm.LoginCommand;

Activity

  1. itg-assistant commented on Jun 17, 2026

    @itg-assistant
    Author

    Julie (ITG) answered 2026-04-21 14:48:59 UTC

    Application.Update(this)
    

    works when

    this
    

    is a Wisej control. But in your case,

    this
    

    is the ViewModel. So don't use

    Application.Update(this).
    

    Instead, you can save the context before the await by doing:

    var context = Application.Current.
    

    Then when you need to update the UI you can do:

    Application.Update(context);
    

    More information on Application.Current: https://docs.wisej.com/api/wisej.web/general/application#current

  2. itg-assistant commented on Jun 17, 2026

    @itg-assistant
    Author

    Alex Prinias answered 2026-04-21 18:38:25 UTC

    Dear Julie,
    thanks for your answer.

    So you mean in the definition of the LoginCommand in the ViewModel's constructor:

    LoginCommand = new Command(

                execute: async () => { var context = Application.Current; await LoginAsync(); Application.Update(context); },...

    However I find it a bit strange, in the sense I would expect my ViewModel to be unaware of Wisej's Application.Current etc. What if I wanted to use the same ViewModel for a WinForms application and not a Wisej one?

    Best regards,
    Alex

  3. itg-assistant commented on Jun 17, 2026

    @itg-assistant
    Author

    Julie (ITG) answered 2026-04-23 14:19:41 UTC

    You're correct that the call to Application.Update does not have to happen in the ViewModel.

    Here's a sample showing how to do async commands in Wisej MVVM.

    • The async method should be in the ViewModel,

    • Navigation or shell swapping should happen in an application-level ViewModel reacting to authentication state

    • Any Wisej-specific Application.Update(...) usage should be hidden in infrastructure that restores/pushes the Wisej context rather than called from the ViewModel itself.

    • In the sample, look at:

    • LoginViewModel.cs for the async login logic

    • ApplicationViewModel.cs for shell swapping (MainViewModel and LoginViewModel are the shells)

    • WisejAsyncCommand.cs and WisejUiDispatcher.cs for the Wisej-aware command/context handling

    • WisejUIDispatcher for the call to Application.Update

    • Window1.cs for the shell host.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    GeneralQuestions, how-tos and everything else.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions