How to prevent specific UWP TreeView node from reordering

Viewed 66

I include TreeView in my UWP application for Folder View support. But I want my root folder can't be dragged or any item can't be placed before my root folder. Actually, I want to reorder any items except root.

enter image description here

Like the above picture, I want to reorder childNode one, two, or three but I don't want to re-order the root.

I don't want the below picture scenario.

enter image description here

How I can implement this in the UWP application?

Here is a sample of my code:

MainPage.xaml

<Page
    x:Class="TreeView.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:TreeView"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

    <Grid>
        <TreeView Name="KeywordTreeView"
                  ItemsSource="{x:Bind Nodes}"
                  CanDragItems="True"
                  CanReorderItems="True">
            <TreeView.ItemTemplate>
                <DataTemplate x:DataType="local:Node">
                    <TreeViewItem ItemsSource="{x:Bind ChildNodes}"
                                  IsExpanded="True"
                                  AllowDrop="True"
                                  CanDrag="True"
                                  Content="{x:Bind Name}"/>
                </DataTemplate>
            </TreeView.ItemTemplate>
        </TreeView>
    </Grid>
</Page>

MainPage.xaml.cs

namespace TreeView
{
    /// <summary>
    /// An empty page that can be used on its own or navigated to within a Frame.
    /// </summary>
    public sealed partial class MainPage : Page
    {
        public MainPage()
        {
            this.InitializeComponent();

            this.Nodes = new ObservableCollection<Node>();
            Node root = new Node("Root");
            Node childnodeone = new Node("ChildNode One");
            Node childnodetwo = new Node("ChildNode Two");
            Node childnodethree = new Node("ChildNode Three");

            root.ChildNodes.Add(childnodeone);
            root.ChildNodes.Add(childnodetwo);
            root.ChildNodes.Add(childnodethree);

            this.Nodes.Add(root);

        }

        public ObservableCollection<Node> Nodes { get; }
    }
    public class Node
    {
        public Node(string name)
        {
            this.Name = name;
        }

        public string Name { get; }
        public ObservableCollection<Node> ChildNodes { get; } = new ObservableCollection<Node>();
    }
}

Can anyone help me with how I can implement this behavior in the UWP application programmatically?

1 Answers

If you want to realize cancel feature, you could judge if current TreeViewNode is correct for DragItems in the DragItemsCompleted event handler like the following. When DragStarting please use temp collection to record current treeview itemsource. Then check if your drag item's parent is correct in drag completed event handler. if not, you could rollback the itemsource with temp object.

private void ListControl_DragItemsCompleted(ListViewBase sender, DragItemsCompletedEventArgs args)
{
    foreach (var item in args.Items)
    {

        var node = MyTreeView.NodeFromContainer(MyTreeView.ContainerFromItem(item));          
        var parent = node.Parent;

      //do some stuff judge the parent.
    }
}  
Related