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

Commit fe0e8c0

Browse files
author
gumme
committed
Fixes the following in RegisterXamlComponentRecursive method (called for example on Paste):
- Getting the correct namescope for RootItem (the INameScope case was not checked). - Clears the local namescope for the object if it exists, otherwise name changes will be registered in the local namespace instead of RootItem document namespace. - Only adds _Copy (or CopyX, where X is an integer) if the previous name did not already end with _Copy. This prevents names as "myname_Copy_Copy_Copy..." to occur when copying and pasting already copied elements. - Registers the new name to the RootItem namescope, only setting site.Name is not enough as its not yet a part of the RootItem document namescope.
1 parent 21a4a33 commit fe0e8c0

2 files changed

Lines changed: 59 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.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)