如何在 AvaloniaUI 中将自定义事件从子 UserControl 提升到父控件
How to raise a custom event from child UserControl to parent control in AvaloniaUI
在 dotnet 的 Avalonia-UI 框架中。
我有一个 UserControl
,它是一个带有“关闭”按钮的“关于”弹出视图,应该向父控件发出一个自定义事件,以指示该弹出窗口应由其父 window 关闭。
到目前为止,我似乎几乎拥有它,但我找不到引发事件的方法。
这是我的:
在 AboutView.axaml
我有:
<UserControl ... >
<Button Command="{Binding OnCloseView}" >Close</Button>
在AboutViewModel.cs
中我定义了一个ReactiveCommand:
public ReactiveCommand<Unit, Unit> OnCloseView { get; }
public AboutViewModel()
{
OnCloseView = ReactiveCommand.Create(() => { });
}
在 AboutView.axaml.cs
的代码后面我有:
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);
}
父MainWindow.axaml
:
<views:AboutView ExitView="SomeCodeBehindEventHandler" IsVisible="{Binding $parent.DataContext.IsAboutVisible}"/>
在代码隐藏中MainWindow.axaml.cs
:
public void OnAboutViewExitHandler(object sender, RoutedEventArgs e)
{
var viewModel = (MainWindowViewModel)this.DataContext;
viewModel.OnCloseAboutPopup.Execute();
e.Handled=true;
}
我的问题是:
如何从代码中引发 RoutedEvent“ExitView”?
axaml 中是否有更好的方法将事件绑定到父视图模型中的 ReactiveCommand
?
我找不到绑定它的方法,因为它无法编译:
<views:AboutView ExitView="{Binding OnCloseAboutPopup}"/>
如果我找不到更好的方法,那么我将不得不将一个函数传递给代码隐藏并从那里调用 ReactiveCommand。
- 有没有其他更好的方法将事件从子控件发送到父控件?
您需要在构建事件参数时指定路由事件。
var eventArgs = new RoutedEventArgs { RoutedEvent = ExitViewEvent };
在 dotnet 的 Avalonia-UI 框架中。
我有一个 UserControl
,它是一个带有“关闭”按钮的“关于”弹出视图,应该向父控件发出一个自定义事件,以指示该弹出窗口应由其父 window 关闭。
到目前为止,我似乎几乎拥有它,但我找不到引发事件的方法。 这是我的:
在 AboutView.axaml
我有:
<UserControl ... >
<Button Command="{Binding OnCloseView}" >Close</Button>
在AboutViewModel.cs
中我定义了一个ReactiveCommand:
public ReactiveCommand<Unit, Unit> OnCloseView { get; }
public AboutViewModel()
{
OnCloseView = ReactiveCommand.Create(() => { });
}
在 AboutView.axaml.cs
的代码后面我有:
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);
}
父MainWindow.axaml
:
<views:AboutView ExitView="SomeCodeBehindEventHandler" IsVisible="{Binding $parent.DataContext.IsAboutVisible}"/>
在代码隐藏中MainWindow.axaml.cs
:
public void OnAboutViewExitHandler(object sender, RoutedEventArgs e)
{
var viewModel = (MainWindowViewModel)this.DataContext;
viewModel.OnCloseAboutPopup.Execute();
e.Handled=true;
}
我的问题是:
如何从代码中引发 RoutedEvent“ExitView”?
axaml 中是否有更好的方法将事件绑定到父视图模型中的
ReactiveCommand
? 我找不到绑定它的方法,因为它无法编译:
<views:AboutView ExitView="{Binding OnCloseAboutPopup}"/>
如果我找不到更好的方法,那么我将不得不将一个函数传递给代码隐藏并从那里调用 ReactiveCommand。
- 有没有其他更好的方法将事件从子控件发送到父控件?
您需要在构建事件参数时指定路由事件。
var eventArgs = new RoutedEventArgs { RoutedEvent = ExitViewEvent };