Skip to content

Commit a156f3d

Browse files
committed
new helper class for drag drop of files from explorer, fixes #58
1 parent 591a6bb commit a156f3d

2 files changed

Lines changed: 280 additions & 2 deletions

File tree

SimpleSample/MainWindow.xaml.cs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1-
using System.IO;
1+
using System;
2+
using System.IO;
23
using System.Text;
34
using System.Windows;
45
using System.Windows.Controls;
56
using System.Xml;
7+
using ICSharpCode.WpfDesign;
68
using ICSharpCode.WpfDesign.Designer.Services;
79
using ICSharpCode.WpfDesign.Designer.Xaml;
810
using ICSharpCode.WpfDesign.XamlDom;
@@ -29,12 +31,26 @@ public MainWindow()
2931
var loadSettings = new XamlLoadSettings();
3032
loadSettings.DesignerAssemblies.Add(this.GetType().Assembly);
3133

34+
DragFileToDesignPanelHelper.Install(designSurface, CreateItemsOnDragCallback);
3235
using (var xmlReader = XmlReader.Create(new StringReader(xaml)))
3336
{
3437
designSurface.LoadDesigner(xmlReader, loadSettings);
3538
}
3639
}
37-
40+
41+
private DesignItem[] CreateItemsOnDragCallback(DesignContext context, DragEventArgs e)
42+
{
43+
var data = e.Data.GetData(DataFormats.FileDrop, false);
44+
if (data == null)
45+
return null;
46+
var item = context.Services.Component.RegisterComponentForDesigner(new TextBlock());
47+
item.Properties.GetProperty(FrameworkElement.WidthProperty).SetValue(300.0);
48+
item.Properties.GetProperty(FrameworkElement.HeightProperty).SetValue(30.0);
49+
string[] fileList = (string[])data;
50+
item.Properties.GetProperty(TextBlock.TextProperty).SetValue(string.Join(Environment.NewLine, fileList));
51+
return new[] { item };
52+
}
53+
3854
private void lstControls_SelectionChanged(object sender, SelectionChangedEventArgs e)
3955
{
4056
var item = lstControls.SelectedItem as ToolBoxItem;
Lines changed: 262 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,262 @@
1+
// Copyright (c) 2019 AlphaSierraPapa for the SharpDevelop Team
2+
//
3+
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
4+
// software and associated documentation files (the "Software"), to deal in the Software
5+
// without restriction, including without limitation the rights to use, copy, modify, merge,
6+
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
7+
// to whom the Software is furnished to do so, subject to the following conditions:
8+
//
9+
// The above copyright notice and this permission notice shall be included in all copies or
10+
// substantial portions of the Software.
11+
//
12+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
13+
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
14+
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
15+
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
16+
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
17+
// DEALINGS IN THE SOFTWARE.
18+
19+
using System.Linq;
20+
using System.Windows;
21+
using System;
22+
using System.Collections.Generic;
23+
using ICSharpCode.WpfDesign.Designer.Xaml;
24+
using System.Windows.Controls;
25+
26+
namespace ICSharpCode.WpfDesign.Designer.Services
27+
{
28+
/// <summary>
29+
/// A helper for DragDrop files to a DesignPanel
30+
/// </summary>
31+
public class DragFileToDesignPanelHelper
32+
{
33+
protected ChangeGroup ChangeGroup;
34+
35+
MoveLogic moveLogic;
36+
Point createPoint;
37+
38+
Func<DesignContext, DragEventArgs, DesignItem[]> _createItems;
39+
DesignPanel _designPanel;
40+
41+
42+
public static DragFileToDesignPanelHelper Install(DesignSurface designSurface, Func<DesignContext, DragEventArgs, DesignItem[]> createItems)
43+
{
44+
var helper = new DragFileToDesignPanelHelper();
45+
helper._createItems = createItems;
46+
helper._designPanel = designSurface._designPanel as DesignPanel;
47+
48+
helper._designPanel.AllowDrop = true;
49+
helper._designPanel.DragOver += helper.designPanel_DragOver;
50+
helper._designPanel.Drop += helper.designPanel_Drop;
51+
helper._designPanel.DragLeave += helper.designPanel_DragLeave;
52+
53+
return helper;
54+
}
55+
56+
public void Remove()
57+
{
58+
_designPanel.DragOver -= designPanel_DragOver;
59+
_designPanel.Drop -= designPanel_Drop;
60+
_designPanel.DragLeave -= designPanel_DragLeave;
61+
}
62+
63+
void designPanel_DragOver(object sender, DragEventArgs e)
64+
{
65+
try
66+
{
67+
IDesignPanel designPanel = (IDesignPanel)sender;
68+
e.Effects = DragDropEffects.Copy;
69+
e.Handled = true;
70+
Point p = e.GetPosition(designPanel);
71+
72+
if (moveLogic == null)
73+
{
74+
if (ChangeGroup != null)
75+
{
76+
ChangeGroup.Abort();
77+
ChangeGroup = null;
78+
}
79+
ChangeGroup = designPanel.Context.RootItem.OpenGroup("Add Control");
80+
designPanel.IsAdornerLayerHitTestVisible = false;
81+
DesignPanelHitTestResult result = designPanel.HitTest(p, false, true, HitTestType.Default);
82+
83+
if (result.ModelHit != null)
84+
{
85+
designPanel.Focus();
86+
var items = CreateItemsWithPosition(designPanel.Context, e.GetPosition(result.ModelHit.View), e);
87+
if (items != null)
88+
{
89+
if (AddItems(result.ModelHit, items))
90+
{
91+
moveLogic = new MoveLogic(items[0]);
92+
93+
foreach (var designItem in items)
94+
{
95+
if (designPanel.Context.Services.Component is XamlComponentService)
96+
{
97+
((XamlComponentService)designPanel.Context.Services.Component).RaiseComponentRegisteredAndAddedToContainer(designItem);
98+
}
99+
}
100+
createPoint = p;
101+
}
102+
else
103+
{
104+
ChangeGroup.Abort();
105+
ChangeGroup = null;
106+
}
107+
}
108+
else
109+
{
110+
e.Effects = DragDropEffects.None;
111+
}
112+
}
113+
}
114+
else if ((moveLogic.ClickedOn.View as FrameworkElement).IsLoaded)
115+
{
116+
if (moveLogic.Operation == null)
117+
{
118+
moveLogic.Start(createPoint);
119+
}
120+
else
121+
{
122+
moveLogic.Move(p);
123+
}
124+
}
125+
}
126+
catch (Exception x)
127+
{
128+
DragDropExceptionHandler.RaiseUnhandledException(x);
129+
}
130+
}
131+
132+
void designPanel_Drop(object sender, DragEventArgs e)
133+
{
134+
try
135+
{
136+
if (moveLogic != null)
137+
{
138+
moveLogic.Stop();
139+
if (moveLogic.ClickedOn.Services.Tool.CurrentTool is CreateComponentTool)
140+
{
141+
moveLogic.ClickedOn.Services.Tool.CurrentTool = moveLogic.ClickedOn.Services.Tool.PointerTool;
142+
}
143+
moveLogic.DesignPanel.IsAdornerLayerHitTestVisible = true;
144+
moveLogic = null;
145+
ChangeGroup.Commit();
146+
ChangeGroup = null;
147+
148+
e.Handled = true;
149+
}
150+
}
151+
catch (Exception x)
152+
{
153+
DragDropExceptionHandler.RaiseUnhandledException(x);
154+
}
155+
}
156+
157+
void designPanel_DragLeave(object sender, DragEventArgs e)
158+
{
159+
try
160+
{
161+
if (moveLogic != null)
162+
{
163+
moveLogic.Cancel();
164+
moveLogic.ClickedOn.Services.Selection.SetSelectedComponents(null);
165+
moveLogic.DesignPanel.IsAdornerLayerHitTestVisible = true;
166+
moveLogic = null;
167+
ChangeGroup.Abort();
168+
ChangeGroup = null;
169+
170+
}
171+
}
172+
catch (Exception x)
173+
{
174+
DragDropExceptionHandler.RaiseUnhandledException(x);
175+
}
176+
}
177+
178+
private DesignItem[] CreateItemsWithPosition(DesignContext context, Point position, DragEventArgs e)
179+
{
180+
var items = _createItems(context, e); //CreateItems(context, e);
181+
if (items != null)
182+
{
183+
foreach (var designItem in items)
184+
{
185+
designItem.Position = position;
186+
}
187+
}
188+
189+
return items;
190+
}
191+
192+
private DesignItem[] CreateItems(DesignContext context, DragEventArgs e)
193+
{
194+
var item = context.Services.Component.RegisterComponentForDesigner(new Image());
195+
item.Properties.GetProperty(FrameworkElement.WidthProperty).SetValue(100.0);
196+
item.Properties.GetProperty(FrameworkElement.HeightProperty).SetValue(100.0);
197+
return new[] { item };
198+
}
199+
200+
private bool AddItems(DesignItem container, DesignItem[] createdItems)
201+
{
202+
var sizes = createdItems.Select(x =>
203+
{
204+
var fe = x.Component as FrameworkElement;
205+
if (fe != null &&
206+
fe.ReadLocalValue(FrameworkElement.WidthProperty) != DependencyProperty.UnsetValue &&
207+
fe.ReadLocalValue(FrameworkElement.HeightProperty) != DependencyProperty.UnsetValue)
208+
{
209+
return new Rect(x.Position, new Size(fe.Width, fe.Height));
210+
}
211+
return new Rect(x.Position, ModelTools.GetDefaultSize(x));
212+
}).ToList();
213+
214+
return AddItemsWithCustomSize(container, createdItems, sizes);
215+
}
216+
217+
private bool AddItemsWithCustomSize(DesignItem container, DesignItem[] createdItems, IList<Rect> positions)
218+
{
219+
PlacementOperation operation = null;
220+
221+
while (operation == null && container != null)
222+
{
223+
operation = PlacementOperation.TryStartInsertNewComponents(
224+
container,
225+
createdItems,
226+
positions,
227+
PlacementType.AddItem
228+
);
229+
230+
if (operation != null)
231+
break;
232+
233+
try
234+
{
235+
if (container.Parent != null)
236+
{
237+
var rel = container.View.TranslatePoint(new Point(0, 0), container.Parent.View);
238+
for (var index = 0; index < positions.Count; index++)
239+
{
240+
positions[index] = new Rect(new Point(positions[index].X + rel.X, positions[index].Y + rel.Y), positions[index].Size);
241+
}
242+
}
243+
}
244+
catch (Exception)
245+
{ }
246+
247+
container = container.Parent;
248+
}
249+
250+
if (operation != null)
251+
{
252+
container.Services.Selection.SetSelectedComponents(createdItems);
253+
operation.Commit();
254+
return true;
255+
}
256+
else
257+
{
258+
return false;
259+
}
260+
}
261+
}
262+
}

0 commit comments

Comments
 (0)