The following forum(s) have migrated to Microsoft Q&A (Preview): Developing Universal Windows apps!
Visit Microsoft Q&A (Preview) to post new questions.

Learn More

 locked
Drag Items from a TreeView to a ListView RRS feed

  • Question

  • I am building an application that reads all manufacture models from a database and then populates a TreeView Heirarchy to view by manufacturer. This part of my application is working as expected reading the info from a file and the treeview populates correctly.

    I want to be able to select an item from the tree view and add it to the listView. I was trying to do this drag and drop. with no success.

    Is there a way to drag from a TreeView to a list view and have the item dragged over show in the list?

    Sunday, November 3, 2019 10:20 PM

Answers

  • Hi,

    >>Is there a way to drag from a TreeView to a list view and have the item dragged over show in the list?

    Yes, you could drag an item from a TreeView and then drop and show it in the ListView.

    First you need to enable the TreeView.CanDragItems Property (This property is only available in 1809 or higher) for the source TreeView and the ListView.AllowDrop property for the target ListView. Then you need to handle the TreeView.DragItemsStarting Event to put the data you need into the DataPackage. After that, you will also need to handle the ListView.Drop Event to put the data into ListView's source. 

    I've made a simple demo about this. You could refer to the code here.

    In Xaml:

     xmlns:muxc="using:Microsoft.UI.Xaml.Controls"
        
        
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="*"/>
                <RowDefinition Height="*"/>
            </Grid.RowDefinitions>
            <muxc:TreeView  CanDrag="True" CanDragItems="True" DragItemsStarting="TreeView_DragItemsStarting">
                <muxc:TreeView.RootNodes>
                    <muxc:TreeViewNode Content="Flavors"
                               IsExpanded="True">
                        <muxc:TreeViewNode.Children>
                            <muxc:TreeViewNode Content="Vanilla"/>
                            <muxc:TreeViewNode Content="Strawberry"/>
                            <muxc:TreeViewNode Content="Chocolate"/>
                        </muxc:TreeViewNode.Children>
                    </muxc:TreeViewNode>
                </muxc:TreeView.RootNodes>
            </muxc:TreeView>
    
            <ListView x:Name="TargetListView"
                        Grid.Row="1" 
                        AllowDrop="True" 
                      CanReorderItems="True"
                      CanDragItems="True"
                        DragOver="TargetListView_DragOver"
                        Drop="TargetListView_Drop"
                        />
    
        </Grid>

    In codebehind:

    using muxc = Microsoft.UI.Xaml.Controls;
    
     public sealed partial class MainPage : Page
        {
            public ObservableCollection<string> selection { get; set; }
            public MainPage()
            {
                this.InitializeComponent();
                selection = new ObservableCollection<string>();
                selection.Add("123");
                TargetListView.ItemsSource = selection;
            }
    
            private async void TargetListView_Drop(object sender, DragEventArgs e)
            {
                if (e.DataView.Contains(StandardDataFormats.Text))
                {
                    // We need to take a Deferral as we won't be able to confirm the end
                    // of the operation synchronously
                    var def = e.GetDeferral();
                    var s = await e.DataView.GetTextAsync();
                    var items = s.Split('\n');
                    foreach (var item in items)
                    {
                        selection.Add(item);
                    }
                    e.AcceptedOperation = DataPackageOperation.Copy;
                    def.Complete();
                }
            }
    
            private void TargetListView_DragOver(object sender, DragEventArgs e)
            {
                // Our list only accepts text
                e.AcceptedOperation = (e.DataView.Contains(StandardDataFormats.Text)) ? DataPackageOperation.Copy : DataPackageOperation.None;
            }
    
            private void TreeView_DragItemsStarting(Microsoft.UI.Xaml.Controls.TreeView sender, Microsoft.UI.Xaml.Controls.TreeViewDragItemsStartingEventArgs args)
            {
                var data = new StringBuilder();
    
                foreach (var item in args.Items)
                {
                    muxc.TreeViewNode node = (muxc.TreeViewNode)item;
    
                    if (node.Content.ToString().Length > 0) data.Append(node.Content.ToString() as string);
                    
                }
                // Set the content of the DataPackage
                args.Data.SetText(data.ToString());
                // As we want our Reference list to say intact, we only allow Copy
                args.Data.RequestedOperation = DataPackageOperation.Copy;
            }
        }

    This is the code that I'm using to drag a string object from the TreeView and drop it to the ListView. Please note that I'm using TreeView control from Windows UI Library APIs. 

    For more information about Drag and Drop, please refer to the document:https://docs.microsoft.com/en-us/windows/uwp/design/input/drag-and-drop.

    There is a sample about drag and drop here:https://github.com/microsoft/Windows-universal-samples/tree/master/Samples/XamlDragAndDrop

    By the way, We invite you to post new questions in the "Developing Universal Windows apps" forum’s new home on Microsoft Q&A (Preview)!

    Best regards,

    Roy


    "Developing Universal Windows apps" forum will be migrating to a new home on Microsoft Q&A (Preview)!
    We invite you to post new questions in the "Developing Universal Windows apps" forum’s new home on Microsoft Q&A (Preview)!
    For more information, please refer to the sticky post.


    Monday, November 4, 2019 3:25 AM
    Moderator

All replies

  • Hi,

    >>Is there a way to drag from a TreeView to a list view and have the item dragged over show in the list?

    Yes, you could drag an item from a TreeView and then drop and show it in the ListView.

    First you need to enable the TreeView.CanDragItems Property (This property is only available in 1809 or higher) for the source TreeView and the ListView.AllowDrop property for the target ListView. Then you need to handle the TreeView.DragItemsStarting Event to put the data you need into the DataPackage. After that, you will also need to handle the ListView.Drop Event to put the data into ListView's source. 

    I've made a simple demo about this. You could refer to the code here.

    In Xaml:

     xmlns:muxc="using:Microsoft.UI.Xaml.Controls"
        
        
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="*"/>
                <RowDefinition Height="*"/>
            </Grid.RowDefinitions>
            <muxc:TreeView  CanDrag="True" CanDragItems="True" DragItemsStarting="TreeView_DragItemsStarting">
                <muxc:TreeView.RootNodes>
                    <muxc:TreeViewNode Content="Flavors"
                               IsExpanded="True">
                        <muxc:TreeViewNode.Children>
                            <muxc:TreeViewNode Content="Vanilla"/>
                            <muxc:TreeViewNode Content="Strawberry"/>
                            <muxc:TreeViewNode Content="Chocolate"/>
                        </muxc:TreeViewNode.Children>
                    </muxc:TreeViewNode>
                </muxc:TreeView.RootNodes>
            </muxc:TreeView>
    
            <ListView x:Name="TargetListView"
                        Grid.Row="1" 
                        AllowDrop="True" 
                      CanReorderItems="True"
                      CanDragItems="True"
                        DragOver="TargetListView_DragOver"
                        Drop="TargetListView_Drop"
                        />
    
        </Grid>

    In codebehind:

    using muxc = Microsoft.UI.Xaml.Controls;
    
     public sealed partial class MainPage : Page
        {
            public ObservableCollection<string> selection { get; set; }
            public MainPage()
            {
                this.InitializeComponent();
                selection = new ObservableCollection<string>();
                selection.Add("123");
                TargetListView.ItemsSource = selection;
            }
    
            private async void TargetListView_Drop(object sender, DragEventArgs e)
            {
                if (e.DataView.Contains(StandardDataFormats.Text))
                {
                    // We need to take a Deferral as we won't be able to confirm the end
                    // of the operation synchronously
                    var def = e.GetDeferral();
                    var s = await e.DataView.GetTextAsync();
                    var items = s.Split('\n');
                    foreach (var item in items)
                    {
                        selection.Add(item);
                    }
                    e.AcceptedOperation = DataPackageOperation.Copy;
                    def.Complete();
                }
            }
    
            private void TargetListView_DragOver(object sender, DragEventArgs e)
            {
                // Our list only accepts text
                e.AcceptedOperation = (e.DataView.Contains(StandardDataFormats.Text)) ? DataPackageOperation.Copy : DataPackageOperation.None;
            }
    
            private void TreeView_DragItemsStarting(Microsoft.UI.Xaml.Controls.TreeView sender, Microsoft.UI.Xaml.Controls.TreeViewDragItemsStartingEventArgs args)
            {
                var data = new StringBuilder();
    
                foreach (var item in args.Items)
                {
                    muxc.TreeViewNode node = (muxc.TreeViewNode)item;
    
                    if (node.Content.ToString().Length > 0) data.Append(node.Content.ToString() as string);
                    
                }
                // Set the content of the DataPackage
                args.Data.SetText(data.ToString());
                // As we want our Reference list to say intact, we only allow Copy
                args.Data.RequestedOperation = DataPackageOperation.Copy;
            }
        }

    This is the code that I'm using to drag a string object from the TreeView and drop it to the ListView. Please note that I'm using TreeView control from Windows UI Library APIs. 

    For more information about Drag and Drop, please refer to the document:https://docs.microsoft.com/en-us/windows/uwp/design/input/drag-and-drop.

    There is a sample about drag and drop here:https://github.com/microsoft/Windows-universal-samples/tree/master/Samples/XamlDragAndDrop

    By the way, We invite you to post new questions in the "Developing Universal Windows apps" forum’s new home on Microsoft Q&A (Preview)!

    Best regards,

    Roy


    "Developing Universal Windows apps" forum will be migrating to a new home on Microsoft Q&A (Preview)!
    We invite you to post new questions in the "Developing Universal Windows apps" forum’s new home on Microsoft Q&A (Preview)!
    For more information, please refer to the sticky post.


    Monday, November 4, 2019 3:25 AM
    Moderator
  • After some minor tweaks to build my treeview from an observable collection I was able to get this working.

    Thank you for the help.

    Monday, November 4, 2019 12:27 PM