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
相关产品推荐
相关产品推荐

