In dotnet's Avalonia-UI framework.
I have a UserControl
that is an "about" popup view with a "close" button, and should emit a custom event to the parent control to indicate that the popup should be closed by its parent window.
So far it seems I almost have it, but I can't find a way to raise the event. This is what I have:
In The AboutView.axaml
I have:
<UserControl ... >
<Button Command="{Binding OnCloseView}" >Close</Button>
in the AboutViewModel.cs
I have defined a ReactiveCommand:
public ReactiveCommand<Unit, Unit> OnCloseView { get; }
public AboutViewModel()
{
OnCloseView = ReactiveCommand.Create(() => { });
}
in the code behind of the AboutView.axaml.cs
I have:
public AboutView(AboutViewModel viewModel = null)
{
this.InitializeComponent();
var dataContextViewModel = viewModel ?? new AboutViewModel();
this.InitializeComponent();
// ...
dataContextViewModel.OnCloseView.Subscribe(x => {
var eventArgs = new RoutedEventArgs();
// How do I raise the ExitView event from here?
//this.RaiseEvent(eventArgs); // This didn't work, throws null reference exception.
// This didn't work:
//EventHandler handler = ExitView;
//handler?.Invoke(this, eventArgs);
});
this.DataContext = dataContextViewModel;
}
public static readonly RoutedEvent<RoutedEventArgs> ExitViewEvent =
RoutedEvent.Register<AboutView, RoutedEventArgs>(nameof(ExitView), RoutingStrategies.Bubble);
public event EventHandler<RoutedEventArgs> ExitView
{
add => AddHandler(ExitViewEvent, value);
remove => RemoveHandler(ExitViewEvent, value);
}
In the parent MainWindow.axaml
:
<views:AboutView ExitView="SomeCodeBehindEventHandler" IsVisible="{Binding $parent.DataContext.IsAboutVisible}"/>
In the code-behind MainWindow.axaml.cs
:
public void OnAboutViewExitHandler(object sender, RoutedEventArgs e)
{
var viewModel = (MainWindowViewModel)this.DataContext;
viewModel.OnCloseAboutPopup.Execute();
e.Handled=true;
}
The questions I have are:
How do I raise the RoutedEvent "ExitView" from code?
Is there a better way in axaml to bind the event to a ReactiveCommand
in the parent's viewmodel?
I couldn't find a way to bind it since this doesn't compile:
<views:AboutView ExitView="{Binding OnCloseAboutPopup}"/>
If I don't find a better way then I will have to pass a function to the code-behind and invoke the ReactiveCommand from there.
You need to specify the routed event when constructing your event args.
var eventArgs = new RoutedEventArgs { RoutedEvent = ExitViewEvent };