WinUI 3 TreeView右键菜单按钮点击时如何获取绑定的PalleteItem对象
解决WinUI 3 TreeView右键菜单获取对应PalleteItem对象的问题
方法一:直接通过按钮的DataContext获取
你的TreeViewItem的DataContext就是PalleteItem,右键菜单(Flyout)会继承父级的DataContext,所以点击按钮时,按钮的DataContext就是对应的PalleteItem,直接转换即可:
private void DeletePalleteItem_Click(object sender, RoutedEventArgs e) { var button = sender as Button; var palleteItem = button?.DataContext as PalleteItem; if (palleteItem != null) { // 在这里操作目标PalleteItem对象 } }
方法二:通过VisualTreeHelper查找父级TreeViewItem
如果DataContext被意外覆盖,可通过VisualTreeHelper向上查找对应的TreeViewItem,再提取其DataContext:
先实现一个通用的父级查找辅助方法:
private T FindParent<T>(DependencyObject child) where T : DependencyObject { DependencyObject parent = VisualTreeHelper.GetParent(child); if (parent == null) return null; if (parent is T targetParent) { return targetParent; } return FindParent<T>(parent); }
然后在点击事件中调用:
private void DeletePalleteItem_Click(object sender, RoutedEventArgs e) { var button = sender as Button; var treeViewItem = FindParent<TreeViewItem>(button); var palleteItem = treeViewItem?.DataContext as PalleteItem; if (palleteItem != null) { // 在这里操作目标PalleteItem对象 } }
方法三:使用Command绑定(MVVM模式推荐)
如果项目采用MVVM架构,推荐通过绑定Command和CommandParameter的方式,避免后置事件耦合:
- 在ViewModel中定义命令(需引入
CommunityToolkit.Mvvm包或自行实现RelayCommand):
public ICommand DeletePalleteItemCommand { get; } // 在ViewModel构造函数中初始化 public YourViewModel() { DeletePalleteItemCommand = new RelayCommand<PalleteItem>(item => { // 在这里处理删除逻辑,item就是对应的PalleteItem }); }
- 修改XAML中的按钮绑定:
<Button Width="60" Height="60" Command="{Binding DataContext.DeletePalleteItemCommand, RelativeSource={RelativeSource AncestorType=TreeView}}" CommandParameter="{Binding}"> <SymbolIcon Symbol="Delete"/> </Button>
额外优化:右键点击时自动选中TreeViewItem
如果需要右键点击时同步选中该TreeViewItem,可在TreeView的RightTapped事件中处理:
private void TreeView_RightTapped(object sender, RightTappedRoutedEventArgs e) { var frameworkElement = e.OriginalSource as FrameworkElement; while (frameworkElement != null && !(frameworkElement is TreeViewItem)) { frameworkElement = VisualTreeHelper.GetParent(frameworkElement) as FrameworkElement; } if (frameworkElement is TreeViewItem item) { item.IsSelected = true; } }
在TreeView标签上绑定该事件:
<TreeView RightTapped="TreeView_RightTapped" ...>
内容的提问来源于stack exchange,提问作者Ondřej Vacek
相关产品推荐
相关产品推荐

