Search code examples
c#wpflistviewitemtemplate

How to remove dropped item from control where item was dragged from


I'm trying to remove an Object of type Order from an listview which is sent from another listview in the same listview control. The xaml for these listviews is like this:

 <ListView x:Name="listView" HorizontalAlignment="Left" Height="448" ItemsSource="{Binding}" VerticalAlignment="Top" Width="664" Margin="121,43,-2,0">
            <ListView.ItemsPanel>
                <ItemsPanelTemplate>
                    <StackPanel Orientation="Horizontal" Height="100"></StackPanel>
                </ItemsPanelTemplate>
            </ListView.ItemsPanel>
            <ListView.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Vertical">
                        <Button x:Name="Up" Content="^" Click="Up_Click"/>
                        <Button x:Name="Down" Content="v" Click="Down_Click"/>
                        <TextBlock Text="{Binding Chauffeur.Naam}" Width="50"/>
                        <ListView x:Name="Swagnek" ItemsSource="{Binding Orders}" Height="50" AllowDrop="True" DragEnter="ListView_DragEnter" PreviewDragOver="ListView_PreviewDragOver" Drop="ListView_Drop">
                            <ListView.ItemTemplate>
                                <DataTemplate>
                                    <TextBlock x:Name="HoiDoei" HorizontalAlignment="Stretch" Text="{Binding ID}" MouseRightButtonDown="HoiDoei_MouseRightButtonDown" MouseLeftButtonDown="HoiDoei_MouseLeftButtonDown" />
                                </DataTemplate>
                            </ListView.ItemTemplate>
                        </ListView>
                    </StackPanel>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>

So I'm trying to drag and drop orders between two listviews. The problem is that when I've dropped it I have to remove the drag and dropped order from the listview where I dragged it from.

I'm using this c# code.

       private void ListView_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
            {

                var tb = (TextBlock)sender;
                DragDrop.DoDragDrop(this, (Order)tb.DataContext, DragDropEffects.Copy);
            }

   private void ListView_DragEnter(object sender, DragEventArgs e)
        {
            e.Effects = DragDropEffects.Move;
        }

        private void ListView_PreviewDragOver(object sender, DragEventArgs e)
        {
            e.Handled = true;
        }

        private void ListView_Drop(object sender, DragEventArgs e)
        {
            var lv = sender as ListView;
            if (lv.ItemsSource == null)
                lv.ItemsSource = new ObservableCollection<Order>();
            var order = e.Data.GetData(typeof(Order)) as Order;
            var items = lv.ItemsSource as ObservableCollection<Order>;
            items.Add(order);
            orderlist.Remove(order);
        }

It's also possible to drag from an listbox to one of the listviews(not included in the code)

That's why

 orderlist.Remove(order);

is in there


Solution

  • The ItemsSource property of the ListView that you drag the object from should also be set or bound to an ObservableCollection<Order>. Then you should just be able to remove the dropped item from this collection once you have a reference to it:

    ObservableCollection<Order> _source;
    private void ListView_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
    
        var tb = (TextBlock)sender;
        ListView parentListView = FindParent<ListView>(tb);
        if (parentListView != null)
            _source = parentListView.ItemsSource as ObservableCollection<Order>;
        DragDrop.DoDragDrop(this, (Order)tb.DataContext, DragDropEffects.Copy);
    }
    
    public static T FindParent<T>(DependencyObject dependencyObject) where T : DependencyObject
    {
        var parent = VisualTreeHelper.GetParent(dependencyObject);
    
        if (parent == null) return null;
    
        var parentT = parent as T;
        return parentT ?? FindParent<T>(parent);
    }
    
    private void ListView_Drop(object sender, DragEventArgs e)
    {
        var lv = sender as ListView;
        if (lv.ItemsSource == null)
            lv.ItemsSource = new ObservableCollection<Order>();
        var order = e.Data.GetData(typeof(Order)) as Order;
        var items = lv.ItemsSource as ObservableCollection<Order>;
        items.Add(order);
        orderlist.Remove(order);
        if (_source != null && _source.Contains(order))
            _source.Remove(order);
    }