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

WPF中使用Telerik实现GridView单列层级结构的问题

在Telerik WPF GridView中实现列的层级结构

我正在基于WPF的Telerik控件开发嵌套GridView,需要将其中一列设置为层级结构。目前有预期效果参考图,但无对应实现代码。此前已成功实现带拖拽功能的Telerik TreeView(代码附后),尝试将HierarchicalDataTemplate应用到GridViewDataColumn的CellEditTemplate中,但未达到预期效果,当前仅能实现非层级的基础显示。


已实现的带拖拽TreeView代码

ViewModel代码

public class DragDropTreeViewModel : ViewModelBase
{
    private ObservableCollection<TreeItem> _treeItems;
    public ObservableCollection<TreeItem> TreeItems
    {
        get => _treeItems;
        set => SetProperty(ref _treeItems, value);
    }

    public ICommand DragInitializeCommand { get; }
    public ICommand DropCommand { get; }

    public DragDropTreeViewModel()
    {
        TreeItems = new ObservableCollection<TreeItem>
        {
            new TreeItem { Name = "父项1", Children = new ObservableCollection<TreeItem> { new TreeItem { Name = "子项1.1" } } },
            new TreeItem { Name = "父项2" }
        };

        DragInitializeCommand = new DelegateCommand<DragInitializeEventArgs>(OnDragInitialize);
        DropCommand = new DelegateCommand<DragDropEventArgs>(OnDrop);
    }

    private void OnDragInitialize(DragInitializeEventArgs args)
    {
        var treeItem = args.Source as TreeViewItem;
        if (treeItem != null)
        {
            args.Data = treeItem.DataContext;
            args.AllowedEffects = DragDropEffects.Move;
        }
    }

    private void OnDrop(DragDropEventArgs args)
    {
        var draggedItem = args.Data as TreeItem;
        var targetItem = args.Source as TreeViewItem;
        if (draggedItem != null && targetItem != null && draggedItem != targetItem.DataContext)
        {
            // 从原父节点移除
            var oldParent = TreeItems.FirstOrDefault(p => p.Children.Contains(draggedItem));
            oldParent?.Children.Remove(draggedItem);
            // 添加到新父节点
            var newParent = targetItem.DataContext as TreeItem;
            newParent.Children.Add(draggedItem);
        }
    }
}

public class TreeItem : ViewModelBase
{
    private string _name;
    public string Name
    {
        get => _name;
        set => SetProperty(ref _name, value);
    }

    private ObservableCollection<TreeItem> _children;
    public ObservableCollection<TreeItem> Children
    {
        get => _children ??= new ObservableCollection<TreeItem>();
        set => SetProperty(ref _children, value);
    }
}

XAML代码

<UserControl x:Class="DragDropTreeView.Views.DragDropTreeView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation"
             xmlns:local="clr-namespace:DragDropTreeView.ViewModels">
    <UserControl.DataContext>
        <local:DragDropTreeViewModel />
    </UserControl.DataContext>
    <Grid>
        <telerik:RadTreeView ItemsSource="{Binding TreeItems}"
                             telerik:DragDropManager.AllowDrag="True"
                             telerik:DragDropManager.AllowDrop="True">
            <telerik:RadTreeView.ItemTemplate>
                <HierarchicalDataTemplate ItemsSource="{Binding Children}">
                    <TextBlock Text="{Binding Name}" />
                </HierarchicalDataTemplate>
            </telerik:RadTreeView.ItemTemplate>
            <telerik:EventToCommandBehavior.EventBindings>
                <telerik:EventBinding EventName="DragInitialize" Command="{Binding DragInitializeCommand}" />
                <telerik:EventBinding EventName="Drop" Command="{Binding DropCommand}" />
            </telerik:EventToCommandBehavior.EventBindings>
        </telerik:RadTreeView>
    </Grid>
</UserControl>

解决方法

1. 使用Telerik自带的GridViewHierarchicalColumn(推荐)

RadGridView原生提供了层级列控件,无需手动嵌套TreeView,直接配置即可实现层级显示:

<telerik:RadGridView ItemsSource="{Binding ParentDataList}" AutoGenerateColumns="False">
    <telerik:RadGridView.Columns>
        <!-- 层级列 -->
        <telerik:GridViewHierarchicalColumn Header="层级项" DataMemberBinding="{Binding Name}">
            <telerik:GridViewHierarchicalColumn.ItemTemplate>
                <HierarchicalDataTemplate ItemsSource="{Binding Children}">
                    <TextBlock Text="{Binding Name}" />
                </HierarchicalDataTemplate>
            </telerik:GridViewHierarchicalColumn.ItemTemplate>
            <!-- 子层级内容模板 -->
            <telerik:GridViewHierarchicalColumn.HierarchyChildTemplate>
                <telerik:GridViewTemplateColumn>
                    <telerik:GridViewTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <TextBlock Text="{Binding Description}" />
                        </DataTemplate>
                    </telerik:GridViewTemplateColumn.CellTemplate>
                </telerik:GridViewTemplateColumn>
            </telerik:GridViewHierarchicalColumn.HierarchyChildTemplate>
        </telerik:GridViewHierarchicalColumn>
        <!-- 其他普通列 -->
        <telerik:GridViewDataColumn Header="状态" DataMemberBinding="{Binding Status}" />
    </telerik:RadGridView.Columns>
</telerik:RadGridView>

2. 普通列中嵌入TreeView(自定义场景)

如果必须在普通GridViewDataColumn中实现层级,不要使用CellEditTemplate(仅编辑模式生效),改用CellTemplate并嵌套RadTreeView:

<telerik:GridViewDataColumn Header="自定义层级列">
    <telerik:GridViewDataColumn.CellTemplate>
        <DataTemplate>
            <telerik:RadTreeView ItemsSource="{Binding HierarchicalItems}"
                                 IsExpandable="True"
                                 BorderThickness="0"
                                 Margin="0">
                <telerik:RadTreeView.ItemTemplate>
                    <HierarchicalDataTemplate ItemsSource="{Binding Children}">
                        <TextBlock Text="{Binding ItemName}" />
                    </HierarchicalDataTemplate>
                </telerik:RadTreeView.ItemTemplate>
            </telerik:RadTreeView>
        </DataTemplate>
    </telerik:GridViewDataColumn.CellTemplate>
</telerik:GridViewDataColumn>

3. 复用拖拽逻辑

要给GridView中的层级项添加拖拽功能,直接复用之前TreeView的拖拽命令即可:给内部的TreeView添加DragDropManager附加属性,将事件绑定到ViewModel的对应命令上,逻辑和之前TreeView的实现一致。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 10:57:19