我有一个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;
}
}
}
}