1
votes

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>();
1
You could validate by handling the TreeView_DragItemsCompleted event and interogating the args.Items List.McNline
@McNline Thanks. I can get item that I drag and that I had dropped with DragItemsCompleted event. But how can I get object I had dropped onto (target)? Source and target items are inside single TreeView.VladacusB
Was there any helpful answer to this issue? The answer of Xavier Xie didn't help me since all the available callbacks are not executed and give no possibility to stop drop of a node.E.S.

1 Answers

0
votes

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:......
}