Как удалить отброшенный элемент из элемента управления, из которого элемент перетаскивался

Я пытаюсь удалить объект порядка типов из listview, который отправляется из другого listview в том же элементе управления listview. Xaml для этих listviews выглядит следующим образом:

 <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>

Поэтому я пытаюсь перетаскивать заказы между двумя списками.
Проблема в том, что когда я его отбросил, я должен удалить порядок перетаскивания из listview, из которого я его вытащил.

Я использую этот код c#.

       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);
        }

Также можно перетащить из списка в один из listviews(не входит в код)

Вот почему

 orderlist.Remove(order);

быть там

2 ответа

  1. Вместо передачи DataContext TextBlock в качестве данных в действие DragAndDrop передайте сам TextBlock.

        private void ListView_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            DragDrop.DoDragDrop(this, (TextBlock)sender, DragDropEffects.Copy);
        }
    

    Затем в обработчике отбрасывания вы можете получить доступ к ItemsControl (через статические вспомогательные методы), который содержит TextBlock, и с помощью ItemsControl вы можете получить базовую коллекцию ItemsSource.

        private void ListView_Drop(object sender, DragEventArgs e)
        {
            var lv = (ListView)sender;
            if (lv.ItemsSource == null)
            {
                lv.ItemsSource = new ObservableCollection<Order>();
            }
    
            var tb = (TextBlock)e.Data.GetData(typeof(TextBlock));
            var order = (Order)tb.DataContext;
    
            var container = ItemsControl.ContainerFromElement(null, tb);
            var control = ItemsControl.ItemsControlFromItemContainer(container);
            (control.ItemsSource as ICollection<Order>)?.Remove(order);
    
            (lv.ItemsSource as ObservableCollection<Order>)?.Add(order);
    
            orderlist.Remove(order);
        }
    

    Это удалит перетаскиваемый порядок из ItemsControl, в котором он изначально содержался.

  2. Свойство ItemsSource ListView, из которого перетаскивается объект, также должно быть установлено или привязано к an ObservableCollection<Order>. Тогда вы должны просто иметь возможность удалить упавший элемент из этой коллекции, как только у вас есть ссылка на него:

    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);
    }