如何从项目被拖动的控件中删除丢弃的项目

问题描述:

我试图从同一个listview控件中的另一个listview中发送的listview中删除一个类型为Order的对象。这些列表视图的xaml是这样的:如何从项目被拖动的控件中删除丢弃的项目

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

所以我试图拖放两个listviews之间的订单。 问题是,当我放弃它时,我必须从列表视图中删除拖动并从中拖出的顺序。

我正在使用此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); 
     } 

这也可以从一个列表框拖拽到列表视图中的一个(不包括代码)

这就是为什么

orderlist.Remove(order); 

在有

您还应将对象拖动到ListView的ItemsSource属性也设置或绑定到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); 
} 
+0

你是最好的,谢谢你的小解释,让我觉得我学到了东西:) –

强似的TextBlock的DataContext作为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中的拖动订单。

+0

嗨帕特里克,感谢您的回答。问题是,当我从列表框中拖动一个订单,因为订单为空时,它崩溃 –

+0

Kevin,你能够发布ListBox的XAML和C#代码来处理从ListBox启动拖动操作的处理程序吗? –