如何在DragDropCompleted上获得选择的效果

时间:2017-08-10 13:22:10

标签: c# wpf drag-and-drop telerik

我有一个RadTreeView(树视图)和一个RadGridView(gridview)。用户应该能够将元素从gridview移动到树视图,并通过使用shift或control键更改拖放操作的效果(如在Windows资源管理器中)。

在GiveFeedback事件中,效果根据按下的键设置,并且可视化显示预期的行为。但是在Drop事件(在树视图中)和DragDropCompleted事件(在gridview上)中,效果设置为All,因此我无法决定是否必须从当前列表中删除Element。 / p>

我错过了什么吗?

XAML:

    <telerik:RadTreeView AllowDrop="True"
                         ItemsSource="{Binding Folders}"
                         SelectedItem="{Binding SelectedFolder,
                                                Mode=TwoWay}"
                         SelectionMode="Single">
      <telerik:RadTreeView.Resources>
        <HierarchicalDataTemplate DataType="{x:Type local:Folder}" ItemsSource="{Binding Children}">
          <Grid VerticalAlignment="Center">
            <TextBlock VerticalAlignment="Center"
                       Text="{Binding Name}"
                       local:TreeItemDropBehavior.IsEnabled="True" />
          </Grid>
        </HierarchicalDataTemplate>
      </telerik:RadTreeView.Resources>
    </telerik:RadTreeView>
    <telerik:RadGridView Grid.Column="1"
                         AllowDrop="True"
                         AutoGenerateColumns="False"
                         CanUserFreezeColumns="False"
                         CanUserReorderColumns="False"
                         CanUserResizeColumns="False"
                         FontSize="12"
                         IsFilteringAllowed="False"
                         IsReadOnly="True"
                         ItemsSource="{Binding SelectedFolder.Elements}"
                         RowHeight="32"
                         RowIndicatorVisibility="Collapsed"
                         SelectionMode="Multiple"
                         ShowGroupPanel="False"
                         local:GridViewDragDropBehavior.IsEnabled="True"
                         telerik:DragDropManager.AllowCapturedDrag="True"
                         telerik:DragDropManager.AllowDrag="True">
      <telerik:RadGridView.Resources>
        <ResourceDictionary>
          <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary>
              <DataTemplate x:Key="DraggedItemTemplate">
                <StackPanel Orientation="Horizontal">
                  <TextBlock Text="Dragging: " />
                  <TextBlock FontWeight="Bold" Text="{Binding CurrentDraggedItems.Count}" />
                  <TextBlock Text=" Element(s)" />
                </StackPanel>
              </DataTemplate>
            </ResourceDictionary>
          </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
      </telerik:RadGridView.Resources>
      <telerik:RadGridView.Columns>
        <telerik:GridViewDataColumn Width="100"
                                    DataMemberBinding="{Binding Name}"
                                    Header="Name" />
        <telerik:GridViewDataColumn Width="250"
                                    DataMemberBinding="{Binding Description}"
                                    Header="Description" />
      </telerik:RadGridView.Columns>
    </telerik:RadGridView>

GridViewDragDropBehavior:

  public class GridViewDragDropBehavior
  {
    public RadGridView AssociatedControl { get; set; }

    private void SubscribeToDragDropEvents()
    {
      DragDropManager.AddDragInitializeHandler(AssociatedControl, OnDragInitialize);
      DragDropManager.AddGiveFeedbackHandler(AssociatedControl, OnGiveFeedback);
      DragDropManager.AddDragDropCompletedHandler(AssociatedControl, OnDragDropCompleted);
      DragDropManager.AddDragOverHandler(AssociatedControl, OnDragOver);
    }

    private void UnsubscribeFromDragDropEvents()
    {
      DragDropManager.RemoveDragInitializeHandler(AssociatedControl, OnDragInitialize);
      DragDropManager.RemoveGiveFeedbackHandler(AssociatedControl, OnGiveFeedback);
      DragDropManager.RemoveDragDropCompletedHandler(AssociatedControl, OnDragDropCompleted);
      DragDropManager.RemoveDragOverHandler(AssociatedControl, OnDragOver);
    }

    private void OnDragInitialize(object sender, DragInitializeEventArgs e)
    {
      DropIndicationDetails details = new DropIndicationDetails();
      var gridView = sender as RadGridView;
      details.DragSource = gridView.ItemsSource;

      var items = gridView.SelectedItems;
      details.CurrentDraggedItems = items;

      IDragPayload dragPayload = DragDropPayloadManager.GeneratePayload(null);

      dragPayload.SetData("DraggedData", items);
      dragPayload.SetData("DropDetails", details);

      e.Data = dragPayload;

      e.DragVisual = new DragVisual { Content = details, ContentTemplate = AssociatedControl.Resources["DraggedItemTemplate"] as DataTemplate };
      e.DragVisualOffset = new Point(e.RelativeStartPoint.X + 10, e.RelativeStartPoint.Y);
      e.AllowedEffects = DragDropEffects.All;
    }

    private void OnGiveFeedback(object sender, GiveFeedbackEventArgs e)
    {
      Debug.WriteLine("GridViewDragDropBehavior.OnGiveFeedback {0}", e.Effects);
      e.SetCursor(Cursors.Arrow);
      e.Handled = true;
    }

    private void OnDragDropCompleted(object sender, DragDropCompletedEventArgs e)
    {
      Debug.WriteLine("GridViewDragDropBehavior.OnDragDropCompleted: {0}", e.Effects);
      var data = DragDropPayloadManager.GetDataFromObject(e.Data, "DraggedData") as IList;
      var details = DragDropPayloadManager.GetDataFromObject(e.Data, "DropDetails");
      Debug.WriteLine(e.Effects);

      // Remove Element from source list if drag drop effect is move
      /*if (e.Effects == DragDropEffects.Move)
      {
        var collection = (details as DropIndicationDetails).DragSource as IList;
        foreach(var element in data)
        {
          collection.Remove(element);
        }
      }*/
    }

    private void OnDragOver(object sender, Telerik.Windows.DragDrop.DragEventArgs e)
    {
      Debug.WriteLine("GridViewDragDropBehavior.OnDragOver: {0}", e.Effects);
      e.Effects = DragDropEffects.None;
      e.Handled = true;
    }
  }

TreeItemDropBehavior.cs:

  public class TreeItemDropBehavior
  {
    protected virtual void Initialize()
    {
      DragDropManager.AddGiveFeedbackHandler(AssociatedObject, OnGiveFeedback);
      DragDropManager.AddDropHandler(AssociatedObject, OnDrop);
    }

    protected virtual void CleanUp()
    {
      DragDropManager.RemoveGiveFeedbackHandler(AssociatedObject, OnGiveFeedback);
      DragDropManager.RemoveDropHandler(AssociatedObject, OnDrop);
    }

    private void OnGiveFeedback(object sender, Telerik.Windows.DragDrop.GiveFeedbackEventArgs e)
    {
      Debug.WriteLine("TreeItemDropBehavior.OnGiveFeedback {0}", e.Effects);
      e.SetCursor(Cursors.Arrow);
      e.Handled = true;
    }

    private void OnDrop(object sender, Telerik.Windows.DragDrop.DragEventArgs e)
    {
      Debug.WriteLine("TreeItemDropBehavior.OnDrop: {0}", e.Effects);

      if (e.Effects != DragDropEffects.None)
      {
        var destinationItem = (e.OriginalSource as FrameworkElement).ParentOfType<RadTreeViewItem>();
        var data = DragDropPayloadManager.GetDataFromObject(e.Data, "DraggedData") as IList;
        var details = DragDropPayloadManager.GetDataFromObject(e.Data, "DropDetails") as DropIndicationDetails;

        if (destinationItem != null)
        {
          foreach (var element in data)
          {
            (destinationItem.DataContext as Folder).Elements.Add(element as Element);
          }

          e.Handled = true;
        }
      }
    }
  }

0 个答案:

没有答案