如何将父窗口BarButtonItem的ItemClick事件绑定到嵌套子控件对应事件?
WPF嵌套UserControl间事件直接绑定方案
你可以不用中转控件,直接通过两种常见方式实现需求:
方法一:后台代码通过控件树查找并订阅事件
这种方式适合不使用MVVM的简单场景,直接在父窗口后台找到嵌套的目标控件,关联事件逻辑:
- 先在
userTwo的XAML里,把目标BarButtonItem的访问权限设为公开:
<dxb:BarButtonItem x:Name="userTwoBarBtn" x:FieldModifier="public" ItemClick="userTwoBarBtn_ItemClick" />
- 在
windowMain的后台Loaded事件中,逐层查找控件并绑定事件:
private void WindowMain_Loaded(object sender, RoutedEventArgs e) { // 找到第一层子控件userOne var userOne = this.FindName("userOne") as UserOne; if (userOne == null) return; // 从userOne中找到嵌套的userTwo var userTwo = userOne.FindName("userTwo") as UserTwo; if (userTwo == null) return; // 获取userTwo里的目标按钮 var targetBtn = userTwo.userTwoBarBtn; if (targetBtn == null) return; // 让windowMain的按钮点击时,触发目标按钮的ItemClick逻辑 this.mainBarBtn.ItemClick += (s, args) => targetBtn.RaiseItemClick(); // 或者如果userTwo里的事件处理方法是公开的,也可以直接调用: // this.mainBarBtn.ItemClick += userTwo.userTwoBarBtn_ItemClick; }
方法二:使用MVVM命令绑定(推荐)
如果项目采用MVVM模式,把点击逻辑抽离到ViewModel中,让两个按钮绑定同一个命令,彻底解耦控件层级:
- 定义基础的RelayCommand实现:
public class RelayCommand : ICommand { private readonly Action<object> _execute; private readonly Func<object, bool> _canExecute; public RelayCommand(Action<object> execute, Func<object, bool> canExecute = null) { _execute = execute ?? throw new ArgumentNullException(nameof(execute)); _canExecute = canExecute; } public bool CanExecute(object parameter) => _canExecute?.Invoke(parameter) ?? true; public void Execute(object parameter) => _execute(parameter); public event EventHandler CanExecuteChanged { add => CommandManager.RequerySuggested += value; remove => CommandManager.RequerySuggested -= value; } }
- 在共享的ViewModel(比如
MainViewModel)中定义命令:
public class MainViewModel { public ICommand TargetClickCommand { get; } public MainViewModel() { TargetClickCommand = new RelayCommand(ExecuteTargetClick); } private void ExecuteTargetClick(object parameter) { // 这里编写原来userTwo中BarButtonItem的点击逻辑 } }
- 给
windowMain设置DataContext:
<Window.DataContext> <local:MainViewModel /> </Window.DataContext> <!-- 父窗口的BarButtonItem绑定命令 --> <dxb:BarButtonItem ItemClickCommand="{Binding TargetClickCommand}" />
- 在
userTwo的XAML中,绑定同一命令(通过RelativeSource找到上层窗口的DataContext):
<dxb:BarButtonItem ItemClickCommand="{Binding DataContext.TargetClickCommand, RelativeSource={RelativeSource AncestorType=Window}}" />
这样不管控件嵌套多少层,两个按钮都会触发同一个逻辑,完全不需要中转控件,也更符合WPF的设计思想。
内容的提问来源于stack exchange,提问作者Alan
相关产品推荐
相关产品推荐

