I am building a WPF MVVM application. I am trying to load a UserControl
inside a Grid but the OnLoaded
method doesn't fire.
Here is EventTrigger
in the UserControl
, called Selector
:
<b:Interaction.Triggers>
<b:EventTrigger EventName="Loaded">
<b:InvokeCommandAction Command="{Binding onl oadedCommand}" />
</b:EventTrigger>
</b:Interaction.Triggers>
Here is the code in SelectorViewModel
:
public RelayCommand onl oadedCommand { get; set; }
public SelectorViewModel(MapService mapService)
{
this.mapService = mapService ?? throw new ArgumentNullException(nameof(mapService));
onl oadedCommand = new RelayCommand(OnLoaded);
}
public async void OnLoaded()
{
AvailablePositions = await mapService.GetPositions();
//other code
}
The View
of the grid where the UserControl
is loaded into:
<local:Selector Grid.Row="0" Margin="{StaticResource SmallLeftTopMargin}" />
The ViewModel
of the grid, where the UserControl
is loaded into:
public SelectorViewModel SelectorViewModel { get; set; }
public MapViewModel(MapService mapService)
{
SelectorViewModel = new SelectorViewModel(mapService);
}
What could possibly be the reason the method is not called at all? I put a breakpoint in SelectorViewModel
' s constructor and it hits it, but it doesn't hit the one in OnLoaded()
.
Is the fact that the method is async
a problem?
EDIT:
I tried setting the command as:
OnLoadedCommand = new RelayCommand(async () => await onl oaded());
and changing the return type of OnLoaded
from void
to Task
but it still didn't work.
CodePudding user response:
You can bind it with Command
like below. I tested it works.
Xaml Code
<DataGrid>
<i:Interaction.Triggers>
<i:EventTrigger EventName="Loaded">
<i:InvokeCommandAction Command="{Binding onl oadedCommand}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</DataGrid>
ViewModel
class MainWindowViewModel
{
public AsyncCommand onl oadedCommand { get; set; }
public MainWindowViewModel()
{
onl oadedCommand = new AsyncCommand(async () => await onl oaded());
}
public async Task OnLoaded()
{
Console.WriteLine("Loaded");
}
}
Async Command
public interface IAsyncCommand : ICommand
{
Task ExecuteAsync(object parameter);
}
public class AsyncCommand : AsyncCommandBase
{
private readonly Func<Task> _command;
public AsyncCommand(Func<Task> command)
{
_command = command;
}
public override bool CanExecute(object parameter)
{
return true;
}
public override Task ExecuteAsync(object parameter)
{
return _command();
}
}
AsyncCommandBase
public abstract class AsyncCommandBase : IAsyncCommand
{
public abstract bool CanExecute(object parameter);
public abstract Task ExecuteAsync(object parameter);
public async void Execute(object parameter)
{
await ExecuteAsync(parameter);
}
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested = value; }
remove { CommandManager.RequerySuggested -= value; }
}
protected void RaiseCanExecuteChanged()
{
CommandManager.InvalidateRequerySuggested();
}
}
I also recommend you to subscribe to Method as in the link here.
You can check here for more detailed information.