Search code examples
c#wpfmultithreadingasynchronousdata-binding

C# WPF Async Event


This WPF application needs to pass data from a selection in a UserControl back to the parent Window so the data can be used to populate the other UserControls. The selection makes a HTTP request to a database, so it needs to be asynchronous. My current method for passing data from a child UserControl to the parent Window is using a RelayCommand that fires an event.

    public RelayCommand<Project> SelectProjectCommand { get; private set; }
    public event Action<Project> SelectProjectRequested = delegate { };


    public ProjectsViewModel()
    {
        SelectProjectCommand = new RelayCommand<Project>(SelectProject);
    }

    private void SelectProject(Project project)
    {
        SelectProjectRequested(project);
    }

The Main Window subscribes to the SelectProjectRequested event, and when it fires, executes an asynchronous method that gets data from the database.

private async void InitializeSearchView(Project project)
{
    if (project != null)
    {
       await _searchViewModel.GetAllMaterialsForProjectAsync(project);
    }
}

public ViewModel()
{
    _projectsViewModel.SelectProjectRequested += InitializeSearchView;
}

I'm trying to follow asynchronous best practices, and make it asynchronous from top to bottom. However, I can't figure out how to make events asynchronous. I can make an asynch RelayCommand, and I can make asynch methods, but how do I connnect the two with an event? Or is there a better way to connect the data of the UserControl with the data of the Main Window in an asynchronous way?


Solution

  • Why not use AsyncRelayCommand? https://learn.microsoft.com/en-us/dotnet/communitytoolkit/mvvm/asyncrelaycommand

    In general, the when you are dealing with UI events, it is acceptable to use also async void (since they do not need to return anything).

    However, the idea of passing selected element this way is not a best practice I would suggest to rework that part of your logic. Maybe you should also look into Messenger for that ? (https://learn.microsoft.com/en-us/dotnet/communitytoolkit/mvvm/messenger)