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

Commit 8bf2a76

Browse files
author
gumme
committed
Merge remote-tracking branch 'origin/NamescopeFixes'
2 parents 37ae46c + 0516cd1 commit 8bf2a76

3 files changed

Lines changed: 112 additions & 23 deletions

File tree

src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlComponentService.cs

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -90,24 +90,37 @@ internal XamlDesignItem RegisterXamlComponentRecursive(XamlObject obj)
9090
}
9191

9292
if (_context.RootItem != null && !string.IsNullOrEmpty(site.Name)) {
93-
var nameScope = _context.RootItem.Component as INameScope;
94-
nameScope = NameScope.GetNameScope((DependencyObject) _context.RootItem.Component);
95-
var fnd = nameScope.FindName(site.Name);
96-
97-
if (fnd != null) {
98-
string newNm = site.Name + "_Copy";
99-
fnd = nameScope.FindName(newNm);
100-
if (fnd == null)
101-
site.Name = newNm;
102-
else {
93+
var nameScope = NameScopeHelper.GetNameScopeFromObject(_context.RootItem.Component);
94+
95+
if (nameScope != null) {
96+
// The object will be a part of the RootItem namescope, remove local namescope if set
97+
NameScopeHelper.ClearNameScopeProperty(obj.Instance);
98+
99+
string newName = site.Name;
100+
if (nameScope.FindName(newName) != null) {
101+
int copyIndex = newName.LastIndexOf("_Copy", StringComparison.Ordinal);
102+
if (copyIndex < 0) {
103+
newName += "_Copy";
104+
}
105+
else if (!newName.EndsWith("_Copy", StringComparison.Ordinal)) {
106+
string copyEnd = newName.Substring(copyIndex + "_Copy".Length);
107+
int copyEndValue;
108+
if (Int32.TryParse(copyEnd, out copyEndValue))
109+
newName = newName.Remove(copyIndex + "_Copy".Length);
110+
else
111+
newName += "_Copy";
112+
}
113+
103114
int i = 1;
104-
while (fnd != null) {
105-
newNm = site.Name + "_Copy" + i;
106-
fnd = nameScope.FindName(newNm);
107-
i++;
115+
string newNameTemplate = newName;
116+
while (nameScope.FindName(newName) != null) {
117+
newName = newNameTemplate + i++;
108118
}
109-
site.Name = newNm;
119+
120+
site.Name = newName;
110121
}
122+
123+
nameScope.RegisterName(newName, obj.Instance);
111124
}
112125
}
113126
return site;

src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/Designer/EditOperationTests.cs

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,5 +151,58 @@ public void PasteWhenIAddChildSelectedAndCannotAdd()
151151
Assert.AreEqual(_name, grid.ContentProperty.CollectionElements[3].Name);
152152
Assert.AreEqual(grid.ContentProperty.CollectionElements[3], selection.PrimarySelection);
153153
}
154+
155+
[Test]
156+
public void PasteSameElementMultipleTimesCheckCopiesNames()
157+
{
158+
var grid = IntializePasteOperationsTest();
159+
var xamlContext = grid.Context as XamlDesignContext;
160+
Assert.IsNotNull(xamlContext);
161+
162+
var selection = grid.Services.Selection;
163+
var innerGrid = grid.ContentProperty.CollectionElements[0];
164+
165+
selection.SetSelectedComponents(new[] {innerGrid});
166+
xamlContext.XamlEditAction.Paste();
167+
Assert.AreEqual(innerGrid.ContentProperty.CollectionElements[1], selection.PrimarySelection);
168+
169+
selection.SetSelectedComponents(new[] {innerGrid});
170+
xamlContext.XamlEditAction.Paste();
171+
Assert.AreEqual(innerGrid.ContentProperty.CollectionElements[2], selection.PrimarySelection);
172+
173+
selection.SetSelectedComponents(new[] {innerGrid});
174+
xamlContext.XamlEditAction.Paste();
175+
Assert.AreEqual(innerGrid.ContentProperty.CollectionElements[3], selection.PrimarySelection);
176+
177+
selection.SetSelectedComponents(new[] {innerGrid});
178+
xamlContext.XamlEditAction.Paste();
179+
Assert.AreEqual(innerGrid.ContentProperty.CollectionElements[4], selection.PrimarySelection);
180+
181+
Assert.IsNullOrEmpty(innerGrid.ContentProperty.CollectionElements[0].Name);
182+
Assert.AreEqual(_name, innerGrid.ContentProperty.CollectionElements[1].Name);
183+
Assert.AreEqual(_name + "_Copy", innerGrid.ContentProperty.CollectionElements[2].Name);
184+
Assert.AreEqual(_name + "_Copy1", innerGrid.ContentProperty.CollectionElements[3].Name);
185+
Assert.AreEqual(_name + "_Copy2", innerGrid.ContentProperty.CollectionElements[4].Name);
186+
187+
xamlContext.XamlEditAction.Copy(new[] {innerGrid.ContentProperty.CollectionElements[3]});
188+
var cutXaml = Clipboard.GetText(TextDataFormat.Xaml);
189+
Assert.That(cutXaml, Is.StringContaining(":Name=\"" + _name + "_Copy1\""));
190+
191+
selection.SetSelectedComponents(new[] {innerGrid});
192+
xamlContext.XamlEditAction.Paste();
193+
Assert.AreEqual(innerGrid.ContentProperty.CollectionElements[5], selection.PrimarySelection);
194+
Assert.AreEqual(_name + "_Copy3", innerGrid.ContentProperty.CollectionElements[5].Name);
195+
196+
var gridDepObj = grid.Component as DependencyObject;
197+
Assert.IsNotNull(gridDepObj);
198+
var nameScope = NameScope.GetNameScope(gridDepObj);
199+
Assert.IsNotNull(nameScope);
200+
Assert.IsNotNull(nameScope.FindName(_name));
201+
Assert.IsNotNull(nameScope.FindName(_name + "_Copy"));
202+
Assert.IsNotNull(nameScope.FindName(_name + "_Copy1"));
203+
Assert.IsNotNull(nameScope.FindName(_name + "_Copy2"));
204+
Assert.IsNotNull(nameScope.FindName(_name + "_Copy3"));
205+
Assert.IsNull(nameScope.FindName(_name + "_Copy4"));
206+
}
154207
}
155208
}

src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/NameScopeHelper.cs

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,24 +10,19 @@ namespace ICSharpCode.WpfDesign.XamlDom
1010
/// <summary>
1111
/// Static methods to help with <see cref="System.Windows.Markup.INameScope"/> operations on Xaml elements.
1212
/// </summary>
13-
internal static class NameScopeHelper
13+
public static class NameScopeHelper
1414
{
1515
/// <summary>
1616
/// Finds the XAML namescope for the specified object and uses it to unregister the old name and then register the new name.
1717
/// </summary>
1818
/// <param name="namedObject">The object where the name was changed.</param>
1919
/// <param name="oldName">The old name.</param>
2020
/// <param name="newName">The new name.</param>
21-
public static void NameChanged(XamlObject namedObject, string oldName, string newName)
21+
internal static void NameChanged(XamlObject namedObject, string oldName, string newName)
2222
{
2323
var obj = namedObject;
2424
while (obj != null) {
25-
var nameScope = obj.Instance as INameScope;
26-
if (nameScope == null) {
27-
var depObj = obj.Instance as DependencyObject;
28-
if (depObj != null)
29-
nameScope = NameScope.GetNameScope(depObj);
30-
}
25+
var nameScope = GetNameScopeFromObject(obj.Instance);
3126
if (nameScope != null) {
3227
if (oldName != null) {
3328
try {
@@ -52,5 +47,33 @@ public static void NameChanged(XamlObject namedObject, string oldName, string ne
5247
obj = obj.ParentObject;
5348
}
5449
}
50+
51+
/// <summary>
52+
/// Gets the XAML namescope for the specified object.
53+
/// </summary>
54+
/// <param name="obj">The object to get the XAML namescope for.</param>
55+
/// <returns>A XAML namescope, as an <see cref="INameScope"/> instance.</returns>
56+
public static INameScope GetNameScopeFromObject(object obj)
57+
{
58+
var nameScope = obj as INameScope;
59+
if (nameScope == null) {
60+
var depObj = obj as DependencyObject;
61+
if (depObj != null)
62+
nameScope = NameScope.GetNameScope(depObj);
63+
}
64+
65+
return nameScope;
66+
}
67+
68+
/// <summary>
69+
/// Clears the <see cref="NameScope.NameScopeProperty"/> if the object is a <see cref="DependencyObject"/>.
70+
/// </summary>
71+
/// <param name="obj">The object to clear the <see cref="NameScope.NameScopeProperty"/> on.</param>
72+
public static void ClearNameScopeProperty(object obj)
73+
{
74+
var depObj = obj as DependencyObject;
75+
if (depObj != null)
76+
depObj.ClearValue(NameScope.NameScopeProperty);
77+
}
5578
}
5679
}

0 commit comments

Comments
 (0)