Skip to content
This repository was archived by the owner on Oct 16, 2020. It is now read-only.

Commit 82099d6

Browse files
committed
Right Click Context Menu for multiple Selected Items to Wrap them in a Container (Grid or Canvas at the Moment!)
1 parent 961c05c commit 82099d6

File tree

7 files changed

+343
-2
lines changed

7 files changed

+343
-2
lines changed
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<ContextMenu x:Class="ICSharpCode.WpfDesign.Designer.Extensions.RightClickMultipleItemsContextMenu"
2+
xmlns="http://schemas.microsoft.com/netfx/2007/xaml/presentation"
3+
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4+
xmlns:Translation="clr-namespace:ICSharpCode.WpfDesign.Designer"
5+
>
6+
<MenuItem Header="{Binding WrapInCanvas, Source={x:Static Translation:Translations.Instance}}" Click="Click_WrapInCanvas" />
7+
<MenuItem Header="{Binding WrapInGrid, Source={x:Static Translation:Translations.Instance}}" Click="Click_WrapInGrid" />
8+
</ContextMenu>
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
// Copyright (c) 2014 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;
20+
using System.Collections.Generic;
21+
using System.Linq;
22+
using System.Text;
23+
using System.Windows;
24+
using System.Windows.Controls;
25+
using System.Windows.Data;
26+
using System.Windows.Documents;
27+
using System.Windows.Input;
28+
using System.Windows.Media;
29+
using System.Windows.Media.Imaging;
30+
using System.Windows.Navigation;
31+
using System.Windows.Shapes;
32+
using ICSharpCode.WpfDesign.PropertyGrid;
33+
using ICSharpCode.WpfDesign.Designer.Xaml;
34+
35+
namespace ICSharpCode.WpfDesign.Designer.Extensions
36+
{
37+
public partial class RightClickMultipleItemsContextMenu
38+
{
39+
private DesignItem designItem;
40+
41+
public RightClickMultipleItemsContextMenu(DesignItem designItem)
42+
{
43+
this.designItem = designItem;
44+
45+
InitializeComponent();
46+
}
47+
48+
void Click_WrapInCanvas(object sender, System.Windows.RoutedEventArgs e)
49+
{
50+
ModelTools.WrapItemsNewContainer(this.designItem.Services.Selection.SelectedItems, typeof(Canvas));
51+
}
52+
53+
void Click_WrapInGrid(object sender, System.Windows.RoutedEventArgs e)
54+
{
55+
ModelTools.WrapItemsNewContainer(this.designItem.Services.Selection.SelectedItems, typeof(Grid));
56+
}
57+
}
58+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
// Copyright (c) 2014 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;
20+
using System.Windows;
21+
using System.Windows.Media;
22+
using System.Windows.Shapes;
23+
24+
using ICSharpCode.WpfDesign.Adorners;
25+
using ICSharpCode.WpfDesign.Extensions;
26+
using ICSharpCode.WpfDesign.Designer;
27+
28+
namespace ICSharpCode.WpfDesign.Designer.Extensions
29+
{
30+
/// <summary>
31+
///
32+
/// </summary>
33+
[ExtensionServer(typeof(MultipleSelectedExtensionServer))]
34+
[ExtensionFor(typeof(UIElement))]
35+
public class RightClickMultipleItemsContextMenuExtension : SelectionAdornerProvider
36+
{
37+
DesignPanel panel;
38+
39+
protected override void OnInitialized()
40+
{
41+
base.OnInitialized();
42+
43+
panel = ExtendedItem.Context.Services.DesignPanel as DesignPanel;
44+
panel.ContextMenu = new RightClickMultipleItemsContextMenu(ExtendedItem);
45+
}
46+
47+
protected override void OnRemove()
48+
{
49+
panel.ContextMenu = null;
50+
51+
base.OnRemove();
52+
}
53+
}
54+
}

src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/ModelTools.cs

Lines changed: 171 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
using System.Windows.Media;
2828
using System.Windows.Media.Imaging;
2929
using System.Windows.Xps.Serialization;
30+
using ICSharpCode.WpfDesign.Designer.Xaml;
3031

3132
namespace ICSharpCode.WpfDesign.Designer
3233
{
@@ -137,7 +138,7 @@ internal static void CreateVisualTree(this UIElement element)
137138
catch (Exception)
138139
{ }
139140
}
140-
141+
141142
internal static Size GetDefaultSize(DesignItem createdItem)
142143
{
143144
CreateVisualTree(createdItem.View);
@@ -198,5 +199,174 @@ public static void Resize(DesignItem item, double newWidth, double newHeight)
198199
item.Properties.GetProperty(FrameworkElement.HeightProperty).SetValue(newHeight);
199200
}
200201
}
202+
203+
204+
private class ItemPos
205+
{
206+
public HorizontalAlignment HorizontalAlignment{ get; set; }
207+
208+
public VerticalAlignment VerticalAlignment{ get; set; }
209+
210+
public double Xmin { get; set; }
211+
212+
public double Xmax { get; set; }
213+
214+
public double Ymin { get; set; }
215+
216+
public double Ymax { get; set; }
217+
218+
public DesignItem DesignItem { get; set; }
219+
}
220+
221+
public static void WrapItemsNewContainer(IEnumerable<DesignItem> items, Type containerType)
222+
{
223+
var collection = items;
224+
225+
var _context = collection.First().Context as XamlDesignContext;
226+
227+
var oldContainer = collection.First().Parent;
228+
229+
if (collection.Any(x => x.Parent != oldContainer))
230+
return;
231+
232+
var newInstance = Activator.CreateInstance(containerType);
233+
DesignItem newPanel = _context.Services.Component.RegisterComponentForDesigner(newInstance);
234+
var changeGroup = newPanel.OpenGroup("Wrap in Container");
235+
236+
List<ItemPos> itemList = new List<ItemPos>();
237+
238+
foreach (var item in collection) {
239+
240+
var itemPos = new ItemPos(){ DesignItem = item };
241+
itemList.Add(itemPos);
242+
243+
if (oldContainer.Component is Canvas) {
244+
var canvas = oldContainer.View as Canvas;
245+
246+
if (item.Properties.GetAttachedProperty(Canvas.RightProperty) != null && item.Properties.GetAttachedProperty(Canvas.RightProperty).IsSet) {
247+
itemPos.HorizontalAlignment = HorizontalAlignment.Right;
248+
itemPos.Xmax = canvas.ActualWidth - (double)item.Properties.GetAttachedProperty(Canvas.RightProperty).ValueOnInstance;
249+
itemPos.Xmin = itemPos.Xmax - ((FrameworkElement)item.View).ActualWidth;
250+
}
251+
else if (item.Properties.GetAttachedProperty(Canvas.LeftProperty) != null && item.Properties.GetAttachedProperty(Canvas.LeftProperty).IsSet) {
252+
itemPos.HorizontalAlignment = HorizontalAlignment.Left;
253+
itemPos.Xmin = (double)item.Properties.GetAttachedProperty(Canvas.LeftProperty).ValueOnInstance;
254+
itemPos.Xmax = itemPos.Xmin + ((FrameworkElement)item.View).ActualWidth;
255+
} else {
256+
itemPos.HorizontalAlignment = HorizontalAlignment.Left;
257+
itemPos.Xmax = itemPos.Xmin + ((FrameworkElement)item.View).ActualWidth;
258+
}
259+
260+
if (item.Properties.GetAttachedProperty(Canvas.BottomProperty) != null && item.Properties.GetAttachedProperty(Canvas.BottomProperty).IsSet) {
261+
itemPos.VerticalAlignment = VerticalAlignment.Bottom;
262+
itemPos.Ymax = canvas.ActualHeight - (double)item.Properties.GetAttachedProperty(Canvas.BottomProperty).ValueOnInstance;
263+
itemPos.Ymin = itemPos.Ymax - ((FrameworkElement)item.View).ActualHeight;
264+
}
265+
else if (item.Properties.GetAttachedProperty(Canvas.TopProperty) != null && item.Properties.GetAttachedProperty(Canvas.TopProperty).IsSet) {
266+
itemPos.VerticalAlignment = VerticalAlignment.Top;
267+
itemPos.Ymin = (double)item.Properties.GetAttachedProperty(Canvas.TopProperty).ValueOnInstance;
268+
itemPos.Ymax = itemPos.Ymin + ((FrameworkElement)item.View).ActualHeight;
269+
} else {
270+
itemPos.VerticalAlignment = VerticalAlignment.Top;
271+
itemPos.Ymax = itemPos.Ymin + ((FrameworkElement)item.View).ActualHeight;
272+
}
273+
274+
item.Properties.GetAttachedProperty(Canvas.RightProperty).Reset();
275+
item.Properties.GetAttachedProperty(Canvas.LeftProperty).Reset();
276+
item.Properties.GetAttachedProperty(Canvas.TopProperty).Reset();
277+
item.Properties.GetAttachedProperty(Canvas.BottomProperty).Reset();
278+
} else if (oldContainer.Component is Grid) {
279+
var grid = oldContainer.View as Grid;
280+
281+
if ((HorizontalAlignment)item.Properties.GetProperty(FrameworkElement.HorizontalAlignmentProperty).ValueOnInstance == HorizontalAlignment.Right) {
282+
itemPos.HorizontalAlignment = HorizontalAlignment.Right;
283+
itemPos.Xmax = grid.ActualWidth - ((Thickness)item.Properties.GetProperty(FrameworkElement.MarginProperty).ValueOnInstance).Right;
284+
itemPos.Xmin = itemPos.Xmax - ((FrameworkElement)item.View).ActualWidth;
285+
} else {
286+
itemPos.HorizontalAlignment = HorizontalAlignment.Left;
287+
itemPos.Xmin = ((Thickness)item.Properties.GetProperty(FrameworkElement.MarginProperty).ValueOnInstance).Left;
288+
itemPos.Xmax = itemPos.Xmin + ((FrameworkElement)item.View).ActualWidth;
289+
}
290+
291+
if ((VerticalAlignment)item.Properties.GetProperty(FrameworkElement.VerticalAlignmentProperty).ValueOnInstance == VerticalAlignment.Bottom) {
292+
itemPos.VerticalAlignment = VerticalAlignment.Bottom;
293+
itemPos.Ymax = grid.ActualHeight - ((Thickness)item.Properties.GetProperty(FrameworkElement.MarginProperty).ValueOnInstance).Bottom;
294+
itemPos.Ymin = itemPos.Ymax - ((FrameworkElement)item.View).ActualHeight;
295+
} else {
296+
itemPos.VerticalAlignment = VerticalAlignment.Top;
297+
itemPos.Ymin = ((Thickness)item.Properties.GetProperty(FrameworkElement.MarginProperty).ValueOnInstance).Top;
298+
itemPos.Ymax = itemPos.Ymin + ((FrameworkElement)item.View).ActualHeight;
299+
}
300+
301+
item.Properties.GetProperty(FrameworkElement.HorizontalAlignmentProperty).Reset();
302+
item.Properties.GetProperty(FrameworkElement.VerticalAlignmentProperty).Reset();
303+
item.Properties.GetProperty(FrameworkElement.MarginProperty).Reset();
304+
}
305+
306+
var parCol = item.ParentProperty.CollectionElements;
307+
parCol.Remove(item);
308+
}
309+
310+
var xmin = itemList.Min(x => x.Xmin);
311+
var xmax = itemList.Max(x => x.Xmax);
312+
var ymin = itemList.Min(x => x.Ymin);
313+
var ymax = itemList.Max(x => x.Ymax);
314+
315+
if (oldContainer.Component is Canvas) {
316+
newPanel.Properties.GetProperty(FrameworkElement.WidthProperty).SetValue(xmax - xmin);
317+
newPanel.Properties.GetProperty(FrameworkElement.HeightProperty).SetValue(ymax - ymin);
318+
newPanel.Properties.GetAttachedProperty(Canvas.LeftProperty).SetValue(xmin);
319+
newPanel.Properties.GetAttachedProperty(Canvas.TopProperty).SetValue(ymin);
320+
} else if (oldContainer.Component is Grid) {
321+
newPanel.Properties.GetProperty(FrameworkElement.HorizontalAlignmentProperty).SetValue(HorizontalAlignment.Left);
322+
newPanel.Properties.GetProperty(FrameworkElement.VerticalAlignmentProperty).SetValue(VerticalAlignment.Top);
323+
newPanel.Properties.GetProperty(FrameworkElement.MarginProperty).SetValue(new Thickness(xmin, ymin, 0, 0));
324+
newPanel.Properties.GetProperty(FrameworkElement.WidthProperty).SetValue(xmax - xmin);
325+
newPanel.Properties.GetProperty(FrameworkElement.HeightProperty).SetValue(ymax - ymin);
326+
}
327+
328+
foreach (var item in itemList) {
329+
newPanel.ContentProperty.CollectionElements.Add(item.DesignItem);
330+
331+
if (newPanel.Component is Canvas) {
332+
if (item.HorizontalAlignment == HorizontalAlignment.Right) {
333+
item.DesignItem.Properties.GetAttachedProperty(Canvas.RightProperty).SetValue(xmax - item.Xmax);
334+
} else {
335+
item.DesignItem.Properties.GetAttachedProperty(Canvas.LeftProperty).SetValue(item.Xmin - xmin);
336+
}
337+
338+
if (item.VerticalAlignment == VerticalAlignment.Bottom) {
339+
item.DesignItem.Properties.GetAttachedProperty(Canvas.BottomProperty).SetValue(ymax - item.Ymax);
340+
} else {
341+
item.DesignItem.Properties.GetAttachedProperty(Canvas.TopProperty).SetValue(item.Ymin - ymin);
342+
}
343+
} else if (newPanel.Component is Grid) {
344+
Thickness thickness = new Thickness(0);
345+
if (item.HorizontalAlignment == HorizontalAlignment.Right) {
346+
item.DesignItem.Properties.GetProperty(FrameworkElement.HorizontalAlignmentProperty).SetValue(HorizontalAlignment.Right);
347+
thickness.Right = xmax - item.Xmax;
348+
} else {
349+
item.DesignItem.Properties.GetProperty(FrameworkElement.HorizontalAlignmentProperty).SetValue(HorizontalAlignment.Left);
350+
thickness.Left = item.Xmin - xmin;
351+
}
352+
353+
if (item.VerticalAlignment == VerticalAlignment.Bottom) {
354+
item.DesignItem.Properties.GetProperty(FrameworkElement.VerticalAlignmentProperty).SetValue(VerticalAlignment.Bottom);
355+
thickness.Bottom = ymax - item.Ymax;
356+
} else {
357+
item.DesignItem.Properties.GetProperty(FrameworkElement.VerticalAlignmentProperty).SetValue(VerticalAlignment.Top);
358+
thickness.Top = item.Ymin - ymin;
359+
}
360+
361+
item.DesignItem.Properties.GetProperty(FrameworkElement.MarginProperty).SetValue(thickness);
362+
}
363+
}
364+
365+
oldContainer.ContentProperty.CollectionElements.Add(newPanel);
366+
367+
changeGroup.Commit();
368+
369+
_context.Services.Selection.SetSelectedComponents(new []{ newPanel });
370+
}
201371
}
202372
}

src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Translations.cs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,5 +65,23 @@ public virtual string PressAltText {
6565
return "Press \"Alt\" to Enter Container";
6666
}
6767
}
68+
69+
public virtual string WrapInCanvas {
70+
get {
71+
return "Wrap in Canvas";
72+
}
73+
}
74+
75+
public virtual string WrapInGrid {
76+
get {
77+
return "Wrap in Grid";
78+
}
79+
}
80+
81+
public virtual string WrapInBorder {
82+
get {
83+
return "Wrap in Border";
84+
}
85+
}
6886
}
6987
}

src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/WpfDesign.Designer.csproj

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,10 @@
9090
</Compile>
9191
<Compile Include="Extensions\RenderTransformOriginExtension.cs" />
9292
<Compile Include="Extensions\RightClickContextMenuExtension.cs" />
93+
<Compile Include="Extensions\RightClickMultipleItemsContextMenuExtension.cs" />
94+
<Compile Include="Extensions\RightClickMultipleItemsContextMenu.xaml.cs">
95+
<DependentUpon>RightClickMultipleItemsContextMenu.xaml</DependentUpon>
96+
</Compile>
9397
<Compile Include="Extensions\SkewThumbExtension.cs" />
9498
<Compile Include="Extensions\TopLeftContainerDragHandleMultipleItems.cs" />
9599
<Compile Include="PropertyGrid\Editors\ColorEditor.xaml.cs">
@@ -263,6 +267,7 @@
263267
</ItemGroup>
264268
<ItemGroup>
265269
<Page Include="Extensions\RightClickContextMenu.xaml" />
270+
<Page Include="Extensions\RightClickMultipleItemsContextMenu.xaml" />
266271
<Page Include="PropertyGrid\Editors\ColorEditor.xaml" />
267272
<Page Include="PropertyGrid\Editors\FlatCollectionEditor.xaml" />
268273
<Page Include="PropertyGrid\Editors\OpenCollectionEditor.xaml" />

0 commit comments

Comments
 (0)