wpf mvvm 树 TreeView 搜索 展开树

备注

使用handycontrol + propertychanged.fody

工具类

ViewModelBase

 [AddINotifyPropertyChangedInterface]
    public class ViewModelBase
    {

    }

树形结构配置

public class VMMapTree : ViewModelBase
    {
        /// <summary>
        /// 文件夹显示的名称
        /// </summary>

        public string DirName { get; set; }

        /// <summary>
        /// 地图数据
        /// </summary>
        public ObservableCollection<MapDataConfig> MapDataList { get; set; }
    }

viewmodel

public class VMOfflineMap : ViewModelBase
    {
        private string searchText;

        /// <summary>
        /// 地图列表树
        /// </summary>
        public ObservableCollection<VMMapTree> MapList { get; set; }


        /// <summary>
        /// 筛选数据后的地图列表树
        /// </summary>
        public ICollectionView FilterMapList { get; set; }

        /// <summary>
        /// 搜索文本
        /// </summary>
        public string SearchText
        {
            get => searchText; set
            {
                searchText = value;
                FilterMapList.Refresh();
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public VMOfflineMap()
        {
            UpdateMapList();
        }

        /// <summary>
        /// 更新地图列表
        /// </summary>
        public void UpdateMapList()
        {
            //将地图数据映射成独立的对象避免引用原数据后误操作
            List<MapDataConfig> mapConfigList = null;
            var mapData = MapConfigSingleton.Instance.ConfigList;
            if (mapData.IsNullOrEmpty())
            {
                mapData = new();
            }
            else
            {
                mapConfigList = mapData.AutoMap<MapDataConfig, MapDataConfig>().ToList();
            }


            //菜单树
            var groupData = mapData.GroupBy(f => f.VirtualDirName);
            MapList = new ObservableCollection<VMMapTree>();
            foreach (var group in groupData)
            {
                var mapTree = new VMMapTree()
                {
                    DirName = group.Key,
                    MapDataList = new ObservableCollection<MapDataConfig>()
                };
                foreach (var item in group)
                {
                    mapTree.MapDataList.Add(item);
                }
                MapList.Add(mapTree);
            }


            FilterMapList = CollectionViewSource.GetDefaultView(MapList);
            FilterMapList.Filter = FilterMapTree;
        }

        private bool FilterMapTree(object obj)
        {
            if (string.IsNullOrEmpty(SearchText))
            {
                return true;
            }

            //VMMapTree
            var tree = obj as VMMapTree;

            if (tree.DirName.Contains(SearchText))
            {
                return true;
            }

            if (!tree.MapDataList.IsNullOrEmpty() && tree.MapDataList.Any(f => f.MapName.Contains(SearchText)))
            {
                return true;
            }

            //输入框与选择的列表一致时重置列表(此时为选择了某条数据直接重置)
            //if (SelectedSchool != null && SelectedSchool.schoolName == SchoolText)
            //{
            //    return true;
            //}

            return false;
        }
    }

页面

<TreeView ItemsSource="{Binding FilterMapList}" Style="{x:Null}" BorderThickness="0">
                                <TreeView.Resources>
                                    <HierarchicalDataTemplate DataType="{x:Type vm:VMMapTree}" ItemsSource="{Binding MapDataList}">
                                        <StackPanel Orientation="Horizontal">
                                            <Image Source="/src/img/Common/folder.png" Width="16" Height="16" Margin="0,0,5,0"/>
                                            <TextBlock Text="{Binding DirName}"/>
                                        </StackPanel>
                                    </HierarchicalDataTemplate>
                                    <DataTemplate DataType="{x:Type map:MapDataConfig}">
                                        <StackPanel Orientation="Horizontal">
                                            <Image Source="/src/img/Common/folder.png" Width="16" Height="16" Margin="0,0,5,0" />
                                            <TextBlock Text="{Binding MapName}" ToolTip="{Binding MapName}" VerticalAlignment="Center"/>
                                            <Button Cursor="Hand" Background="{x:Null}" BorderThickness="0">
                                                <Image Source="/src/img/Common/folder.png" Width="16" Height="16" Margin="0,0,5,0"/>
                                            </Button>
                                        </StackPanel>
                                    </DataTemplate>
                                </TreeView.Resources>
                                <TreeView.ItemContainerStyle >
                                    <Style TargetType="TreeViewItem" BasedOn="{StaticResource {x:Type TreeViewItem}}">
                                        <Setter Property="IsExpanded" Value="True"/>
                                    </Style>
                                </TreeView.ItemContainerStyle>
                            </TreeView>
posted @ 2025-06-19 15:25  Hey,Coder!  阅读(35)  评论(0)    收藏  举报