mirror of
https://gitee.com/akwkevin/aistudio.-wpf.-diagram
synced 2026-04-26 19:23:24 +08:00
添加项目文件。
This commit is contained in:
31
gong-wpf-dragdrop/src/Showcase/Models/ClonableItemModel.cs
Normal file
31
gong-wpf-dragdrop/src/Showcase/Models/ClonableItemModel.cs
Normal file
@@ -0,0 +1,31 @@
|
||||
using System;
|
||||
|
||||
namespace Showcase.WPF.DragDrop.Models
|
||||
{
|
||||
public class ClonableItemModel : ItemModel, ICloneable
|
||||
{
|
||||
public ClonableItemModel()
|
||||
{
|
||||
}
|
||||
|
||||
public ClonableItemModel(int itemIndex)
|
||||
: base(itemIndex)
|
||||
{
|
||||
}
|
||||
|
||||
public object Clone()
|
||||
{
|
||||
var clonableItemModel = new ClonableItemModel();
|
||||
clonableItemModel.BindableDoubleValue = this.BindableDoubleValue;
|
||||
clonableItemModel.SubItemCollection.Clear();
|
||||
foreach (var subItem in this.SubItemCollection)
|
||||
{
|
||||
clonableItemModel.SubItemCollection.Add(subItem);
|
||||
}
|
||||
clonableItemModel.SelectedSubItem = this.SelectedSubItem;
|
||||
clonableItemModel.Index = this.Index;
|
||||
clonableItemModel.Caption = $"Cloned Item {this.Index}";
|
||||
return clonableItemModel;
|
||||
}
|
||||
}
|
||||
}
|
||||
13
gong-wpf-dragdrop/src/Showcase/Models/DataGridRowModel.cs
Normal file
13
gong-wpf-dragdrop/src/Showcase/Models/DataGridRowModel.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
using Faker;
|
||||
|
||||
namespace Showcase.WPF.DragDrop.Models
|
||||
{
|
||||
public class DataGridRowModel
|
||||
{
|
||||
public string Name { get; set; } = Faker.Name.FullName(NameFormats.Standard);
|
||||
|
||||
public string StreetName { get; set; } = Faker.Address.StreetName();
|
||||
|
||||
public string City { get; set; } = Faker.Address.City();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace Showcase.WPF.DragDrop.Models
|
||||
{
|
||||
public class DragAdornerTemplateSelector : DataTemplateSelector
|
||||
{
|
||||
public DataTemplate TemplateEven { get; set; }
|
||||
|
||||
public DataTemplate TemplateOdd { get; set; }
|
||||
|
||||
public override DataTemplate SelectTemplate(object item, DependencyObject container)
|
||||
{
|
||||
var itemModel = item as ItemModel;
|
||||
return itemModel != null && (itemModel.Index & 0x01) == 0 ? TemplateEven : TemplateOdd;
|
||||
}
|
||||
}
|
||||
}
|
||||
41
gong-wpf-dragdrop/src/Showcase/Models/GroupedDropHandler.cs
Normal file
41
gong-wpf-dragdrop/src/Showcase/Models/GroupedDropHandler.cs
Normal file
@@ -0,0 +1,41 @@
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using GongSolutions.Wpf.DragDrop;
|
||||
|
||||
namespace Showcase.WPF.DragDrop.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// Custom drop handler which is used for the grouping example.
|
||||
/// </summary>
|
||||
public class GroupedDropHandler : IDropTarget
|
||||
{
|
||||
public void DragOver(IDropInfo dropInfo)
|
||||
{
|
||||
// Call default DragOver method, cause most stuff should work by default
|
||||
GongSolutions.Wpf.DragDrop.DragDrop.DefaultDropHandler.DragOver(dropInfo);
|
||||
if (dropInfo.TargetGroup == null)
|
||||
{
|
||||
dropInfo.Effects = System.Windows.DragDropEffects.None;
|
||||
}
|
||||
}
|
||||
|
||||
public void Drop(IDropInfo dropInfo)
|
||||
{
|
||||
// The default drop handler don't know how to set an item's group. You need to explicitly set the group on the dropped item like this.
|
||||
GongSolutions.Wpf.DragDrop.DragDrop.DefaultDropHandler.Drop(dropInfo);
|
||||
|
||||
// Now extract the dragged group items and set the new group (target)
|
||||
var data = DefaultDropHandler.ExtractData(dropInfo.Data).OfType<GroupedItem>().ToList();
|
||||
foreach (var groupedItem in data)
|
||||
{
|
||||
groupedItem.Group = dropInfo.TargetGroup.Name.ToString();
|
||||
}
|
||||
|
||||
// Changing group data at runtime isn't handled well: force a refresh on the collection view.
|
||||
if (dropInfo.TargetCollection is ICollectionView)
|
||||
{
|
||||
((ICollectionView)dropInfo.TargetCollection).Refresh();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
52
gong-wpf-dragdrop/src/Showcase/Models/GroupedItem.cs
Normal file
52
gong-wpf-dragdrop/src/Showcase/Models/GroupedItem.cs
Normal file
@@ -0,0 +1,52 @@
|
||||
using System.ComponentModel;
|
||||
using System.Runtime.CompilerServices;
|
||||
using JetBrains.Annotations;
|
||||
|
||||
namespace Showcase.WPF.DragDrop.Models
|
||||
{
|
||||
public class GroupedItem : INotifyPropertyChanged
|
||||
{
|
||||
private string _caption;
|
||||
private string _group;
|
||||
|
||||
public GroupedItem(int group, int item)
|
||||
{
|
||||
this.Caption = $"Item {item} from Group {group}";
|
||||
this._group = $"Group {group}";
|
||||
}
|
||||
|
||||
public string Caption
|
||||
{
|
||||
get { return _caption; }
|
||||
set
|
||||
{
|
||||
if (value == _caption) return;
|
||||
_caption = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public string Group
|
||||
|
||||
{
|
||||
get { return _group; }
|
||||
set
|
||||
{
|
||||
if (value == _group)
|
||||
{
|
||||
return;
|
||||
}
|
||||
_group = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
[NotifyPropertyChangedInvocator]
|
||||
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
|
||||
{
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||
}
|
||||
}
|
||||
}
|
||||
155
gong-wpf-dragdrop/src/Showcase/Models/ItemModel.cs
Normal file
155
gong-wpf-dragdrop/src/Showcase/Models/ItemModel.cs
Normal file
@@ -0,0 +1,155 @@
|
||||
using System;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Windows.Input;
|
||||
using JetBrains.Annotations;
|
||||
using Showcase.WPF.DragDrop.ViewModels;
|
||||
|
||||
namespace Showcase.WPF.DragDrop.Models
|
||||
{
|
||||
public class ItemModel : INotifyPropertyChanged
|
||||
{
|
||||
private double _bindableDoubleValue;
|
||||
private string _selectedSubItem;
|
||||
|
||||
public ItemModel()
|
||||
{
|
||||
this.BindableDoubleValue = Faker.RandomNumber.Next(0, 100);
|
||||
for (int i = 0; i < Faker.RandomNumber.Next(2, 20); i++)
|
||||
{
|
||||
SubItemCollection.Add(new SubItemModel($"Sub item {i}"));
|
||||
}
|
||||
}
|
||||
|
||||
public ItemModel(int itemIndex)
|
||||
: this()
|
||||
{
|
||||
this.Index = itemIndex;
|
||||
this.Caption = $"Item {itemIndex}";
|
||||
}
|
||||
|
||||
public int Index { get; set; }
|
||||
|
||||
public string Caption { get; set; }
|
||||
|
||||
public ObservableCollection<SubItemModel> SubItemCollection { get; set; } = new ObservableCollection<SubItemModel>();
|
||||
|
||||
public string SelectedSubItem
|
||||
{
|
||||
get { return _selectedSubItem; }
|
||||
set
|
||||
{
|
||||
if (value == _selectedSubItem) return;
|
||||
_selectedSubItem = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public double BindableDoubleValue
|
||||
{
|
||||
get { return _bindableDoubleValue; }
|
||||
set
|
||||
{
|
||||
if (value.Equals(_bindableDoubleValue)) return;
|
||||
_bindableDoubleValue = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return this.Caption;
|
||||
}
|
||||
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
[NotifyPropertyChangedInvocator]
|
||||
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
|
||||
{
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||
}
|
||||
}
|
||||
|
||||
public class SubItemModel : INotifyPropertyChanged
|
||||
{
|
||||
private string _bindableValue;
|
||||
private bool _bindableOptionA;
|
||||
private bool _bindableOptionB;
|
||||
|
||||
public SubItemModel(string caption)
|
||||
{
|
||||
this.Caption = caption;
|
||||
this.ButtonTestCommand = new SimpleCommand(o => { this.BindableValue = $"Button clicked at {DateTime.UtcNow.ToLocalTime()}"; });
|
||||
}
|
||||
|
||||
public string Caption { get; set; }
|
||||
|
||||
public ICommand ButtonTestCommand { get; set; }
|
||||
|
||||
public string BindableValue
|
||||
{
|
||||
get { return _bindableValue; }
|
||||
set
|
||||
{
|
||||
if (value == _bindableValue) return;
|
||||
_bindableValue = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public bool BindableOptionA
|
||||
{
|
||||
get { return _bindableOptionA; }
|
||||
set
|
||||
{
|
||||
if (value == _bindableOptionA) return;
|
||||
_bindableOptionA = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public bool BindableOptionB
|
||||
{
|
||||
get { return _bindableOptionB; }
|
||||
set
|
||||
{
|
||||
if (value == _bindableOptionB) return;
|
||||
_bindableOptionB = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return this.Caption;
|
||||
}
|
||||
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
[NotifyPropertyChangedInvocator]
|
||||
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
|
||||
{
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class SerializableItemModel
|
||||
{
|
||||
public SerializableItemModel(int itemIndex)
|
||||
{
|
||||
this.Index = itemIndex;
|
||||
this.Caption = $"{itemIndex}. Item";
|
||||
}
|
||||
|
||||
public int Index { get; set; }
|
||||
|
||||
public string Caption { get; set; }
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return this.Caption;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
using GongSolutions.Wpf.DragDrop;
|
||||
|
||||
namespace Showcase.WPF.DragDrop.Models
|
||||
{
|
||||
public class ListBoxCustomDropHandler : DefaultDropHandler
|
||||
{
|
||||
public override void DragOver(IDropInfo dropInfo)
|
||||
{
|
||||
if (dropInfo.VisualTarget == dropInfo.DragInfo.VisualSource)
|
||||
{
|
||||
dropInfo.NotHandled = dropInfo.VisualTarget == dropInfo.DragInfo.VisualSource;
|
||||
}
|
||||
else
|
||||
{
|
||||
base.DragOver(dropInfo);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Drop(IDropInfo dropInfo)
|
||||
{
|
||||
if (dropInfo.VisualTarget == dropInfo.DragInfo.VisualSource)
|
||||
{
|
||||
dropInfo.NotHandled = dropInfo.VisualTarget == dropInfo.DragInfo.VisualSource;
|
||||
}
|
||||
else
|
||||
{
|
||||
base.Drop(dropInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
23
gong-wpf-dragdrop/src/Showcase/Models/NestedDropHandler.cs
Normal file
23
gong-wpf-dragdrop/src/Showcase/Models/NestedDropHandler.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
using System;
|
||||
using System.Windows;
|
||||
using GongSolutions.Wpf.DragDrop;
|
||||
|
||||
namespace Showcase.WPF.DragDrop.Models
|
||||
{
|
||||
public class NestedDropHandler : IDropTarget
|
||||
{
|
||||
public void DragOver(IDropInfo dropInfo)
|
||||
{
|
||||
if (dropInfo.TargetItem?.ToString().StartsWith("Root", StringComparison.OrdinalIgnoreCase) == true)
|
||||
{
|
||||
dropInfo.Effects = DragDropEffects.Move;
|
||||
dropInfo.DropTargetAdorner = DropTargetAdorners.Highlight;
|
||||
}
|
||||
}
|
||||
|
||||
public void Drop(IDropInfo dropInfo)
|
||||
{
|
||||
// nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
105
gong-wpf-dragdrop/src/Showcase/Models/SampleData.cs
Normal file
105
gong-wpf-dragdrop/src/Showcase/Models/SampleData.cs
Normal file
@@ -0,0 +1,105 @@
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using System.Windows.Data;
|
||||
using GongSolutions.Wpf.DragDrop;
|
||||
|
||||
namespace Showcase.WPF.DragDrop.Models
|
||||
{
|
||||
public class SampleData
|
||||
{
|
||||
public SampleData()
|
||||
{
|
||||
for (var n = 0; n < 50; ++n)
|
||||
{
|
||||
this.SerializableCollection1.Add(new SerializableItemModel(n + 1));
|
||||
this.Collection1.Add(new ItemModel(n + 1));
|
||||
this.FilterCollection1.Add(new ItemModel(n + 1));
|
||||
this.ClonableCollection1.Add(new ClonableItemModel(n + 1));
|
||||
this.DataGridCollection1.Add(new DataGridRowModel());
|
||||
}
|
||||
for (var n = 0; n < 10; ++n)
|
||||
{
|
||||
this.Collection4.Add(new ItemModel() { Caption = $"Model {n + 1}" });
|
||||
}
|
||||
|
||||
for (var g = 0; g < 4; ++g)
|
||||
{
|
||||
for (var i = 0; i < ((g % 2) == 0 ? 4 : 2); ++i)
|
||||
{
|
||||
this.GroupedCollection.Add(new GroupedItem(g, i));
|
||||
}
|
||||
}
|
||||
|
||||
this.GroupedItemsCollectionViewSource = CollectionViewSource.GetDefaultView(this.GroupedCollection);
|
||||
this.GroupedItemsCollectionViewSource.GroupDescriptions.Add(new PropertyGroupDescription() { PropertyName = nameof(GroupedItem.Group) });
|
||||
|
||||
for (int r = 1; r <= 6; r++)
|
||||
{
|
||||
var root = new TreeNode($"Root {r}");
|
||||
for (var i = 0; i < ((r % 2) == 0 ? 8 : 3); ++i)
|
||||
{
|
||||
root.Children.Add(new TreeNode($"Item {i + 10 * r}"));
|
||||
}
|
||||
this.TreeCollection1.Add(root);
|
||||
if (r == 2)
|
||||
{
|
||||
root.IsExpanded = true;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
this.TabItemCollection1.Add(new TabItemModel(i + 1));
|
||||
}
|
||||
this.TabItemCollection2.Add(new TabItemModel(1));
|
||||
}
|
||||
|
||||
public ObservableCollection<SerializableItemModel> SerializableCollection1 { get; set; } = new ObservableCollection<SerializableItemModel>();
|
||||
|
||||
public ObservableCollection<SerializableItemModel> SerializableCollection2 { get; set; } = new ObservableCollection<SerializableItemModel>();
|
||||
|
||||
public SerializableDragHandler SerializableDragHandler { get; set; } = new SerializableDragHandler();
|
||||
|
||||
public SerializableDropHandler SerializableDropHandler { get; set; } = new SerializableDropHandler();
|
||||
|
||||
public ObservableCollection<ItemModel> Collection1 { get; set; } = new ObservableCollection<ItemModel>();
|
||||
|
||||
public ObservableCollection<ItemModel> Collection2 { get; set; } = new ObservableCollection<ItemModel>();
|
||||
|
||||
public ObservableCollection<ItemModel> Collection3 { get; set; } = new ObservableCollection<ItemModel>();
|
||||
|
||||
public ObservableCollection<ItemModel> Collection4 { get; set; } = new ObservableCollection<ItemModel>();
|
||||
|
||||
public ObservableCollection<ClonableItemModel> ClonableCollection1 { get; set; } = new ObservableCollection<ClonableItemModel>();
|
||||
|
||||
public ObservableCollection<ClonableItemModel> ClonableCollection2 { get; set; } = new ObservableCollection<ClonableItemModel>();
|
||||
|
||||
public ObservableCollection<ItemModel> FilterCollection1 { get; set; } = new ObservableCollection<ItemModel>();
|
||||
|
||||
public ObservableCollection<ItemModel> FilterCollection2 { get; set; } = new ObservableCollection<ItemModel>();
|
||||
|
||||
public ObservableCollection<TreeNode> TreeCollection1 { get; set; } = new ObservableCollection<TreeNode>();
|
||||
|
||||
public ObservableCollection<TreeNode> TreeCollection2 { get; set; } = new ObservableCollection<TreeNode>();
|
||||
|
||||
public GroupedDropHandler GroupedDropHandler { get; set; } = new GroupedDropHandler();
|
||||
|
||||
public ObservableCollection<GroupedItem> GroupedCollection { get; set; } = new ObservableCollection<GroupedItem>();
|
||||
|
||||
public ICollectionView GroupedItemsCollectionViewSource { get; }
|
||||
|
||||
public ObservableCollection<DataGridRowModel> DataGridCollection1 { get; set; } = new ObservableCollection<DataGridRowModel>();
|
||||
|
||||
public ObservableCollection<DataGridRowModel> DataGridCollection2 { get; set; } = new ObservableCollection<DataGridRowModel>();
|
||||
|
||||
public ObservableCollection<TabItemModel> TabItemCollection1 { get; set; } = new ObservableCollection<TabItemModel>();
|
||||
|
||||
public ObservableCollection<TabItemModel> TabItemCollection2 { get; set; } = new ObservableCollection<TabItemModel>();
|
||||
|
||||
public TextBoxCustomDropHandler TextBoxCustomDropHandler { get; set; } = new TextBoxCustomDropHandler();
|
||||
|
||||
public ListBoxCustomDropHandler ListBoxCustomDropHandler { get; set; } = new ListBoxCustomDropHandler();
|
||||
|
||||
public IDropTarget NestedDropHandler { get; set; } = new NestedDropHandler();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Windows;
|
||||
using GongSolutions.Wpf.DragDrop;
|
||||
using GongSolutions.Wpf.DragDrop.Utilities;
|
||||
|
||||
namespace Showcase.WPF.DragDrop.Models
|
||||
{
|
||||
[Serializable]
|
||||
public class SerializableWrapper
|
||||
{
|
||||
public IEnumerable<object> Items { get; set; }
|
||||
|
||||
public DragDropKeyStates DragDropCopyKeyState { get; set; }
|
||||
}
|
||||
|
||||
public class SerializableDragHandler : IDragSource
|
||||
{
|
||||
private bool alreadyDropped = false;
|
||||
|
||||
public void StartDrag(IDragInfo dragInfo)
|
||||
{
|
||||
alreadyDropped = false;
|
||||
var items = dragInfo.SourceItems.OfType<object>().ToList();
|
||||
var wrapper = new SerializableWrapper()
|
||||
{
|
||||
Items = items,
|
||||
DragDropCopyKeyState = DragDropKeyStates.ControlKey //dragInfo.DragDropCopyKeyState
|
||||
};
|
||||
dragInfo.Data = wrapper;
|
||||
dragInfo.DataFormat = DataFormats.GetDataFormat(DataFormats.Serializable);
|
||||
dragInfo.Effects = dragInfo.Data != null ? DragDropEffects.Copy | DragDropEffects.Move : DragDropEffects.None;
|
||||
}
|
||||
|
||||
public bool CanStartDrag(IDragInfo dragInfo)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public void Dropped(IDropInfo dropInfo)
|
||||
{
|
||||
alreadyDropped = true;
|
||||
}
|
||||
|
||||
public void DragDropOperationFinished(DragDropEffects operationResult, IDragInfo dragInfo)
|
||||
{
|
||||
if (alreadyDropped || dragInfo == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// the drag operation has finished on another app
|
||||
if (operationResult != DragDropEffects.None)
|
||||
{
|
||||
if (operationResult.HasFlag(DragDropEffects.Move))
|
||||
{
|
||||
var sourceList = dragInfo.SourceCollection.TryGetList();
|
||||
var items = dragInfo.SourceItems.OfType<object>().ToList();
|
||||
if (sourceList != null)
|
||||
{
|
||||
foreach (var o in items)
|
||||
{
|
||||
sourceList.Remove(o);
|
||||
}
|
||||
}
|
||||
alreadyDropped = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void DragCancelled()
|
||||
{
|
||||
}
|
||||
|
||||
public bool TryCatchOccurredException(Exception exception)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
101
gong-wpf-dragdrop/src/Showcase/Models/SerializableDropHandler.cs
Normal file
101
gong-wpf-dragdrop/src/Showcase/Models/SerializableDropHandler.cs
Normal file
@@ -0,0 +1,101 @@
|
||||
using System;
|
||||
using System.Windows;
|
||||
using GongSolutions.Wpf.DragDrop;
|
||||
using GongSolutions.Wpf.DragDrop.Utilities;
|
||||
|
||||
namespace Showcase.WPF.DragDrop.Models
|
||||
{
|
||||
public class SerializableDropHandler : IDropTarget
|
||||
{
|
||||
public void DragOver(IDropInfo dropInfo)
|
||||
{
|
||||
var wrapper = GetSerializableWrapper(dropInfo);
|
||||
if (wrapper != null && dropInfo.TargetCollection != null)
|
||||
{
|
||||
dropInfo.Effects = ShouldCopyData(dropInfo, wrapper.DragDropCopyKeyState) ? DragDropEffects.Copy : DragDropEffects.Move;
|
||||
dropInfo.DropTargetAdorner = DropTargetAdorners.Insert;
|
||||
}
|
||||
}
|
||||
|
||||
public void Drop(IDropInfo dropInfo)
|
||||
{
|
||||
var wrapper = GetSerializableWrapper(dropInfo);
|
||||
if (wrapper != null && dropInfo.TargetCollection != null)
|
||||
{
|
||||
// at this point the drag info can be null, cause the other app doesn't know it
|
||||
var insertIndex = dropInfo.InsertIndex != dropInfo.UnfilteredInsertIndex ? dropInfo.UnfilteredInsertIndex : dropInfo.InsertIndex;
|
||||
var destinationList = dropInfo.TargetCollection.TryGetList();
|
||||
var copyData = ShouldCopyData(dropInfo, wrapper.DragDropCopyKeyState);
|
||||
|
||||
if (!copyData)
|
||||
{
|
||||
var sourceList = dropInfo.DragInfo?.SourceCollection?.TryGetList();
|
||||
if (sourceList != null)
|
||||
{
|
||||
foreach (var o in wrapper.Items)
|
||||
{
|
||||
var index = sourceList.IndexOf(o);
|
||||
if (index != -1)
|
||||
{
|
||||
sourceList.RemoveAt(index);
|
||||
// so, is the source list the destination list too ?
|
||||
if (destinationList != null && Equals(sourceList, destinationList) && index < insertIndex)
|
||||
{
|
||||
--insertIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (destinationList != null)
|
||||
{
|
||||
// check for cloning
|
||||
var cloneData = dropInfo.Effects.HasFlag(DragDropEffects.Copy)
|
||||
|| dropInfo.Effects.HasFlag(DragDropEffects.Link);
|
||||
foreach (var o in wrapper.Items)
|
||||
{
|
||||
var obj2Insert = o;
|
||||
if (cloneData)
|
||||
{
|
||||
var cloneable = o as ICloneable;
|
||||
if (cloneable != null)
|
||||
{
|
||||
obj2Insert = cloneable.Clone();
|
||||
}
|
||||
}
|
||||
|
||||
destinationList.Insert(insertIndex++, obj2Insert);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static SerializableWrapper GetSerializableWrapper(IDropInfo dropInfo)
|
||||
{
|
||||
var data = dropInfo.Data;
|
||||
|
||||
var dataObject = data as DataObject;
|
||||
if (dataObject != null)
|
||||
{
|
||||
var dataFormat = DataFormats.GetDataFormat(DataFormats.Serializable);
|
||||
data = dataObject.GetDataPresent(dataFormat.Name) ? dataObject.GetData(dataFormat.Name) : data;
|
||||
}
|
||||
|
||||
var wrapper = data as SerializableWrapper;
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
private static bool ShouldCopyData(IDropInfo dropInfo, DragDropKeyStates dragDropCopyKeyState)
|
||||
{
|
||||
// default should always the move action/effect
|
||||
if (dropInfo == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
var copyData = ((dragDropCopyKeyState != default(DragDropKeyStates)) && dropInfo.KeyStates.HasFlag(dragDropCopyKeyState))
|
||||
|| dragDropCopyKeyState.HasFlag(DragDropKeyStates.LeftMouseButton);
|
||||
return copyData;
|
||||
}
|
||||
}
|
||||
}
|
||||
15
gong-wpf-dragdrop/src/Showcase/Models/TabItemModel.cs
Normal file
15
gong-wpf-dragdrop/src/Showcase/Models/TabItemModel.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
namespace Showcase.WPF.DragDrop.Models
|
||||
{
|
||||
public class TabItemModel
|
||||
{
|
||||
public TabItemModel(int itemIndex)
|
||||
{
|
||||
this.Header = $"TabItem {itemIndex}";
|
||||
this.Content = Faker.Lorem.Paragraph();
|
||||
}
|
||||
|
||||
public string Header { get; set; }
|
||||
|
||||
public string Content { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
using System.Linq;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Media;
|
||||
using GongSolutions.Wpf.DragDrop;
|
||||
|
||||
namespace Showcase.WPF.DragDrop.Models
|
||||
{
|
||||
public class TextBoxCustomDropHandler : IDropTarget
|
||||
{
|
||||
public void DragOver(IDropInfo dropInfo)
|
||||
{
|
||||
dropInfo.DropTargetAdorner = typeof(DropTargetHighlightAdorner);
|
||||
dropInfo.Effects = DragDropEffects.Move;
|
||||
}
|
||||
|
||||
public void Drop(IDropInfo dropInfo)
|
||||
{
|
||||
var dataAsList = DefaultDropHandler.ExtractData(dropInfo.Data);
|
||||
((TextBox)dropInfo.VisualTarget).Text = string.Join(", ", dataAsList.OfType<object>().ToArray());
|
||||
}
|
||||
}
|
||||
|
||||
public class DropTargetHighlightAdorner : DropTargetAdorner
|
||||
{
|
||||
private readonly Pen _pen;
|
||||
private readonly Brush _brush;
|
||||
|
||||
public DropTargetHighlightAdorner(UIElement adornedElement, DropInfo dropInfo)
|
||||
: base(adornedElement, dropInfo)
|
||||
{
|
||||
_pen = new Pen(Brushes.Tomato, 2);
|
||||
_pen.Freeze();
|
||||
_brush = new SolidColorBrush(Colors.Coral) { Opacity = 0.2 };
|
||||
this._brush.Freeze();
|
||||
|
||||
this.SetValue(SnapsToDevicePixelsProperty, true);
|
||||
}
|
||||
|
||||
protected override void OnRender(DrawingContext drawingContext)
|
||||
{
|
||||
var visualTarget = this.DropInfo.VisualTarget;
|
||||
if (visualTarget != null)
|
||||
{
|
||||
var translatePoint = visualTarget.TranslatePoint(new Point(), this.AdornedElement);
|
||||
translatePoint.Offset(1, 1);
|
||||
var bounds = new Rect(translatePoint,
|
||||
new Size(visualTarget.RenderSize.Width - 2, visualTarget.RenderSize.Height - 2));
|
||||
drawingContext.DrawRectangle(_brush, _pen, bounds);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
89
gong-wpf-dragdrop/src/Showcase/Models/TreeNode.cs
Normal file
89
gong-wpf-dragdrop/src/Showcase/Models/TreeNode.cs
Normal file
@@ -0,0 +1,89 @@
|
||||
using System;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using System.Runtime.CompilerServices;
|
||||
using JetBrains.Annotations;
|
||||
|
||||
namespace Showcase.WPF.DragDrop.Models
|
||||
{
|
||||
public class TreeNode : INotifyPropertyChanged, ICloneable
|
||||
{
|
||||
private string _caption;
|
||||
private ObservableCollection<TreeNode> _children;
|
||||
private bool _isCloned;
|
||||
private bool _isExpanded;
|
||||
|
||||
public TreeNode(string caption)
|
||||
{
|
||||
this.Caption = caption;
|
||||
this.Children = new ObservableCollection<TreeNode>();
|
||||
}
|
||||
|
||||
public string Caption
|
||||
{
|
||||
get { return _caption; }
|
||||
set
|
||||
{
|
||||
if (value == _caption) return;
|
||||
_caption = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public ObservableCollection<TreeNode> Children
|
||||
{
|
||||
get { return _children; }
|
||||
set
|
||||
{
|
||||
if (Equals(value, _children)) return;
|
||||
_children = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsCloned
|
||||
{
|
||||
get { return _isCloned; }
|
||||
set
|
||||
{
|
||||
if (value == _isCloned) return;
|
||||
_isCloned = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsExpanded
|
||||
{
|
||||
get { return _isExpanded; }
|
||||
set
|
||||
{
|
||||
if (value == _isExpanded) return;
|
||||
_isExpanded = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return this.Caption;
|
||||
}
|
||||
|
||||
public object Clone()
|
||||
{
|
||||
var treeNode = new TreeNode(this.Caption) { IsCloned = true };
|
||||
foreach (var child in this.Children)
|
||||
{
|
||||
treeNode.Children.Add((TreeNode)child.Clone());
|
||||
}
|
||||
return treeNode;
|
||||
}
|
||||
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
[NotifyPropertyChangedInvocator]
|
||||
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
|
||||
{
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user