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

在MAUI应用中实现自定义元素可折叠层级视图的技术问询

MAUI 实现可折叠层级视图(类似文件资源管理器)

1. 定义层级数据模型

先实现包含折叠状态、子项集合的基础模型,需继承INotifyPropertyChanged以支持数据绑定更新:

using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Runtime.CompilerServices;

namespace YourNamespace
{
    public class HierarchyItem : INotifyPropertyChanged
    {
        private bool _isExpanded;
        public bool IsExpanded
        {
            get => _isExpanded;
            set
            {
                _isExpanded = value;
                OnPropertyChanged();
            }
        }

        // 自定义元素属性,根据需求扩展
        public string Name { get; set; }
        public string Icon { get; set; }

        public ObservableCollection<HierarchyItem> Children { get; set; } = new();

        public event PropertyChangedEventHandler PropertyChanged;
        protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

2. 准备ViewModel与测试数据

构建视图模型,初始化层级测试数据,并添加折叠切换命令:

using System.Collections.ObjectModel;
using System.Windows.Input;

namespace YourNamespace
{
    public class MainViewModel
    {
        public ObservableCollection<HierarchyItem> RootItems { get; set; } = new();

        public ICommand ToggleExpandCommand => new Command<HierarchyItem>(item =>
        {
            item.IsExpanded = !item.IsExpanded;
        });

        public MainViewModel()
        {
            // 构造模拟层级数据
            var projectRoot = new HierarchyItem { Name = "MAUI项目", IsExpanded = true };
            var modelsFolder = new HierarchyItem { Name = "Models" };
            modelsFolder.Children.Add(new HierarchyItem { Name = "UserModel.cs" });
            modelsFolder.Children.Add(new HierarchyItem { Name = "OrderModel.cs" });
            projectRoot.Children.Add(modelsFolder);

            var viewsFolder = new HierarchyItem { Name = "Views", IsExpanded = true };
            viewsFolder.Children.Add(new HierarchyItem { Name = "MainPage.xaml" });
            viewsFolder.Children.Add(new HierarchyItem { Name = "DetailPage.xaml" });
            projectRoot.Children.Add(viewsFolder);

            var resourcesFolder = new HierarchyItem { Name = "Resources" };
            resourcesFolder.Children.Add(new HierarchyItem { Name = "Images" });
            resourcesFolder.Children.Add(new HierarchyItem { Name = "Styles.xaml" });
            projectRoot.Children.Add(resourcesFolder);

            RootItems.Add(projectRoot);
        }
    }
}

3. XAML布局实现

通过递归嵌套CollectionView实现层级渲染,用缩进区分父子层级,点击头部切换折叠状态:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:YourNamespace"
             x:Class="YourNamespace.MainPage">
    <ContentPage.BindingContext>
        <local:MainViewModel />
    </ContentPage.BindingContext>

    <CollectionView ItemsSource="{Binding RootItems}"
                    Margin="10"
                    ItemSizingStrategy="MeasureFirstItem">
        <CollectionView.ItemTemplate>
            <DataTemplate>
                <local:HierarchyItemTemplate />
            </DataTemplate>
        </CollectionView.ItemTemplate>
    </CollectionView>
</ContentPage>

将重复的子项模板抽为自定义ContentView(HierarchyItemTemplate.xaml),避免代码冗余:

<ContentView xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:YourNamespace"
             x:Class="YourNamespace.HierarchyItemTemplate">
    <VerticalStackLayout>
        <!-- 折叠/展开头部 -->
        <ContentView Padding="5"
                     BackgroundColor="Transparent">
            <ContentView.GestureRecognizers>
                <TapGestureRecognizer Command="{Binding Source={RelativeSource AncestorType={x:Type local:MainViewModel}}, Path=ToggleExpandCommand}"
                                      CommandParameter="{Binding .}" />
            </ContentView.GestureRecognizers>
            <HorizontalStackLayout Spacing="5">
                <!-- 折叠图标 -->
                <Label Text="{Binding IsExpanded, Converter={StaticResource BoolToIconConverter}, ConverterParameter='▼|▶'}"
                       FontSize="14" />
                <!-- 自定义元素内容 -->
                <Label Text="{Binding Name}"
                       FontSize="14" />
            </HorizontalStackLayout>
        </ContentView>

        <!-- 子项列表,仅展开时显示 -->
        <CollectionView ItemsSource="{Binding Children}"
                        IsVisible="{Binding IsExpanded}"
                        Margin="20,0,0,0"
                        ItemSizingStrategy="MeasureFirstItem">
            <CollectionView.ItemTemplate>
                <DataTemplate>
                    <local:HierarchyItemTemplate />
                </DataTemplate>
            </CollectionView.ItemTemplate>
        </CollectionView>
    </VerticalStackLayout>
</ContentView>

4. 实现布尔转图标转换器

在App.xaml中注册转换器,用于切换折叠/展开图标:

<Application.Resources>
    <ResourceDictionary>
        <local:BoolToIconConverter x:Key="BoolToIconConverter" />
    </ResourceDictionary>
</Application.Resources>

转换器代码:

using System.Globalization;

namespace YourNamespace
{
    public class BoolToIconConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value is bool isExpanded && parameter is string icons)
            {
                var iconPair = icons.Split('|');
                return isExpanded ? iconPair[0] : iconPair[1];
            }
            return "▶";
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
}

优化建议

  • 性能优化:数据量大时,为CollectionView设置ItemsLayout="VerticalList"并启用虚拟化,提升滚动流畅度。
  • 样式定制:可替换头部的Label为Image或FontImageSource,实现更贴近IDE/资源管理器的图标样式。
  • 批量操作:可在ViewModel中添加批量折叠/展开命令,遍历所有层级项设置IsExpanded状态。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 03:12:41