'UWP TreeView how to allow drop for specific item

Using UWP TreeView and working on scenarios where I need to implement drop of one TreeView item to another, depending on it's properties (or type). For example, I have five nodes in TreeView, three of them are files, two are folders. File item can be dropped on Folder - but not vice versa. I can also drag File item from Folder into root but can not drop File item on another item that is also File. So you can see that there are multiple use-cases how TreeView items should behave. Was wondering that I can extend TreeView and then override DragEnter and DragLeave methods, maybe I could then detect underlaying object that is dragged and underlaying object that is dropped to ... but documentation is confusing, too general and lacking. Examples that I have all checked consider all items in TreeView equal (so I can drop Folder on File which is not permissible).

Here is my TreeView:

<TreeView   
            x:Name="treeview" Grid.Row="2" ItemsSource="{Binding storageFolders,Mode=OneWay}" 
            Style="{StaticResource TreeViewStyle1}"
            >
            <TreeView.ItemTemplate>
                <DataTemplate x:DataType="localdata:FolderInfo">
                    <TreeViewItem ItemsSource="{x:Bind subFolders}" Content="{x:Bind FolderName}"/>
                </DataTemplate>
            </TreeView.ItemTemplate>
        </TreeView>

And here is FolderInfo type:

    public class FolderInfo : MyBase //INotifyPropertyChanged
{
    private string _FolderName;
    public string FolderName
    {
        get { return _FolderName; }
        set
        {
            if (_FolderName != value)
            {
                _FolderName = value;
                OnPropertyChanged("FolderName");
            }
        }
    }

    private bool _IsFolder;
    public bool IsFolder
    {
        get { return _IsFolder; }
        set
        {
            if (_IsFolder != value)
            {
                _IsFolder = value;
                OnPropertyChanged("IsFolder");
            }
        }
    }

    public ObservableCollection<FolderInfo> subFolders { get; set; } = new ObservableCollection<FolderInfo>();

    public override string ToString()
    {
        return FolderName;
    }
}

Storage folder is just an ObservableCollection in VM:

public ObservableCollection<FolderInfo> storageFolders { get; set; } = new ObservableCollection<FolderInfo>();


Solution 1:[1]

You could first get all StorageItems by calling DataPackageView.GetStorageItemsAsync method in DragEnter event handler. Then, the IStorageItem interface has a IsOfType(StorageItemTypes) Method, you could use it to check if the StorageItem is folder or file.

private async void DropBorder_DragEnter(object sender, Windows.UI.Xaml.DragEventArgs e)
{
    var items = await e.DataView.GetStorageItemsAsync();
    foreach (IStorageItem storageItem in items)
    {
        Debug.WriteLine("IsFolder: " + storageItem.IsOfType(StorageItemTypes.Folder) + " IsFile: " + storageItem.IsOfType(StorageItemTypes.File));
    }
    //TODO:......
}    

Solution 2:[2]

I came across this thread when trying to figure out how to only allow re-ordering the items in a Treeview. I wanted to prevent the user from dropping an item onto another item with the result being that the dropped item becomes a child node of the item that it was dragged onto. In other words, I wanted to cancel the drop.

I was finally able to get this to work by subscribing to the DragEnter event on the TreeViewItem XAML:

<TreeViewItem DragEnter="Node_DragEnter">

And then I set the AllowDrop property using the DragEventArgs:

private void Node_DragEnter(object sender, DragEventArgs e)
    {
        TreeViewItem source = e.OriginalSource as TreeViewItem;
        source.AllowDrop = false;
    }

Setting AllowDrop to "false" in the XAML had no effect but the above method worked. I thought this might partially answer the question asked on this thread.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Xie Steven
Solution 2 Matt