You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

多选模式下,如何获取Windows.UI.Xaml.Controls.TreeView选中节点

问题解决指南

一、先修复WinUI TreeView的"No such Interface supported"错误

这个错误90%的概率是因为你在DataTemplate里用了系统自带的<TreeViewItem>,而非WinUI命名空间下的<muxc:TreeViewItem>。WinUI的TreeView必须搭配同框架的TreeViewItem使用,否则会出现组件兼容性问题。

修正后的XAML代码

<!-- 确保页面顶部已声明WinUI命名空间:xmlns:muxc="using:Microsoft.UI.Xaml.Controls" -->
<muxc:TreeView SelectionMode="Multiple" Width="300" x:Name="CategoriesTree" 
              ItemsSource="{x:Bind _vm.Categories, Mode=OneWay}"
              SelectionChanged="CategoriesTree_SelectionChanged">
      <muxc:TreeView.ItemTemplate>
            <DataTemplate x:DataType="local1:CategoriesInfo">
                      <!-- 替换为WinUI的TreeViewItem -->
                      <muxc:TreeViewItem ItemsSource="{x:Bind SubCategories}" Content="{x:Bind Name}" />
            </DataTemplate>
      </muxc:TreeView.ItemTemplate>
</muxc:TreeView>

额外检查项

  • 确认项目已安装Microsoft.UI.Xaml NuGet包(建议选稳定版,比如2.8.0)
  • 项目目标最低Windows版本需≥Windows 10 1809(10.0.17763.0),WinUI 2对低版本系统支持有限

二、实现多选选中项的双向绑定

WinUI的TreeView自带的SelectedItems是只读集合,无法直接双向绑定到ViewModel属性,推荐两种解决方案:

方案1:通过SelectionChanged事件同步选中项

在后台代码中监听事件,手动同步到ViewModel的集合:

private void CategoriesTree_SelectionChanged(muxc.TreeView sender, muxc.TreeViewSelectionChangedEventArgs args)
{
    // 清空ViewModel中的选中集合
    _vm.SelectedCategories.Clear();
    // 遍历选中项并添加到ViewModel
    foreach (var item in sender.SelectedItems)
    {
        if (item is CategoriesInfo category)
        {
            _vm.SelectedCategories.Add(category);
        }
    }
}

如果需要反向同步(ViewModel更新时同步TreeView选中状态),可以监听集合变更:

// 假设ViewModel的SelectedCategories是ObservableCollection<CategoriesInfo>
_vm.SelectedCategories.CollectionChanged += (s, e) =>
{
    // 先取消所有选中
    CategoriesTree.DeselectAll();
    // 选中集合内的项
    foreach (var category in _vm.SelectedCategories)
    {
        var container = CategoriesTree.ContainerFromItem(category) as muxc.TreeViewItem;
        container?.IsSelected = true;
    }
};

方案2:自定义附加属性实现双向绑定

封装一个附加属性,让XAML可以直接绑定:

public static class TreeViewHelper
{
    public static readonly DependencyProperty SelectedItemsProperty =
        DependencyProperty.RegisterAttached("SelectedItems", typeof(IList), typeof(TreeViewHelper),
            new PropertyMetadata(null, OnSelectedItemsChanged));

    public static IList GetSelectedItems(DependencyObject obj)
    {
        return (IList)obj.GetValue(SelectedItemsProperty);
    }

    public static void SetSelectedItems(DependencyObject obj, IList value)
    {
        obj.SetValue(SelectedItemsProperty, value);
    }

    private static void OnSelectedItemsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        if (d is muxc.TreeView treeView)
        {
            treeView.SelectionChanged -= OnTreeViewSelectionChanged;
            if (e.NewValue is IList newList)
            {
                treeView.SelectionChanged += OnTreeViewSelectionChanged;
                SyncTreeViewSelection(treeView, newList);
            }
        }
    }

    private static void OnTreeViewSelectionChanged(muxc.TreeView sender, muxc.TreeViewSelectionChangedEventArgs args)
    {
        var selectedItems = GetSelectedItems(sender);
        if (selectedItems == null) return;

        selectedItems.Clear();
        foreach (var item in sender.SelectedItems)
        {
            selectedItems.Add(item);
        }
    }

    private static void SyncTreeViewSelection(muxc.TreeView treeView, IList selectedItems)
    {
        treeView.DeselectAll();
        foreach (var item in selectedItems)
        {
            var container = treeView.ContainerFromItem(item) as muxc.TreeViewItem;
            container?.IsSelected = true;
        }
    }
}

然后在XAML中直接绑定:

<muxc:TreeView SelectionMode="Multiple" Width="300" x:Name="CategoriesTree" 
              ItemsSource="{x:Bind _vm.Categories, Mode=OneWay}"
              local:TreeViewHelper.SelectedItems="{x:Bind _vm.SelectedCategories, Mode=TwoWay}">
      <muxc:TreeView.ItemTemplate>
            <DataTemplate x:DataType="local1:CategoriesInfo">
                      <muxc:TreeViewItem ItemsSource="{x:Bind SubCategories}" Content="{x:Bind Name}" />
            </DataTemplate>
      </muxc:TreeView.ItemTemplate>
</muxc:TreeView>

注意:ViewModel中的SelectedCategories需为ObservableCollection<CategoriesInfo>类型,才能支持双向同步。

内容的提问来源于stack exchange,提问作者Sayansen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 16:45:36