diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlComponentService.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlComponentService.cs
index edbb41d40d..36ca45e8c2 100644
--- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlComponentService.cs
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlComponentService.cs
@@ -90,24 +90,37 @@ namespace ICSharpCode.WpfDesign.Designer.Xaml
}
if (_context.RootItem != null && !string.IsNullOrEmpty(site.Name)) {
- var nameScope = _context.RootItem.Component as INameScope;
- nameScope = NameScope.GetNameScope((DependencyObject) _context.RootItem.Component);
- var fnd = nameScope.FindName(site.Name);
-
- if (fnd != null) {
- string newNm = site.Name + "_Copy";
- fnd = nameScope.FindName(newNm);
- if (fnd == null)
- site.Name = newNm;
- else {
+ var nameScope = NameScopeHelper.GetNameScopeFromObject(_context.RootItem.Component);
+
+ if (nameScope != null) {
+ // The object will be a part of the RootItem namescope, remove local namescope if set
+ NameScopeHelper.ClearNameScopeProperty(obj.Instance);
+
+ string newName = site.Name;
+ if (nameScope.FindName(newName) != null) {
+ int copyIndex = newName.LastIndexOf("_Copy", StringComparison.Ordinal);
+ if (copyIndex < 0) {
+ newName += "_Copy";
+ }
+ else if (!newName.EndsWith("_Copy", StringComparison.Ordinal)) {
+ string copyEnd = newName.Substring(copyIndex + "_Copy".Length);
+ int copyEndValue;
+ if (Int32.TryParse(copyEnd, out copyEndValue))
+ newName = newName.Remove(copyIndex + "_Copy".Length);
+ else
+ newName += "_Copy";
+ }
+
int i = 1;
- while (fnd != null) {
- newNm = site.Name + "_Copy" + i;
- fnd = nameScope.FindName(newNm);
- i++;
+ string newNameTemplate = newName;
+ while (nameScope.FindName(newName) != null) {
+ newName = newNameTemplate + i++;
}
- site.Name = newNm;
+
+ site.Name = newName;
}
+
+ nameScope.RegisterName(newName, obj.Instance);
}
}
return site;
diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/Designer/EditOperationTests.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/Designer/EditOperationTests.cs
index f36c1744e7..9df9884dcf 100644
--- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/Designer/EditOperationTests.cs
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/Designer/EditOperationTests.cs
@@ -151,5 +151,58 @@ namespace ICSharpCode.WpfDesign.Tests.Designer
Assert.AreEqual(_name, grid.ContentProperty.CollectionElements[3].Name);
Assert.AreEqual(grid.ContentProperty.CollectionElements[3], selection.PrimarySelection);
}
+
+ [Test]
+ public void PasteSameElementMultipleTimesCheckCopiesNames()
+ {
+ var grid = IntializePasteOperationsTest();
+ var xamlContext = grid.Context as XamlDesignContext;
+ Assert.IsNotNull(xamlContext);
+
+ var selection = grid.Services.Selection;
+ var innerGrid = grid.ContentProperty.CollectionElements[0];
+
+ selection.SetSelectedComponents(new[] {innerGrid});
+ xamlContext.XamlEditAction.Paste();
+ Assert.AreEqual(innerGrid.ContentProperty.CollectionElements[1], selection.PrimarySelection);
+
+ selection.SetSelectedComponents(new[] {innerGrid});
+ xamlContext.XamlEditAction.Paste();
+ Assert.AreEqual(innerGrid.ContentProperty.CollectionElements[2], selection.PrimarySelection);
+
+ selection.SetSelectedComponents(new[] {innerGrid});
+ xamlContext.XamlEditAction.Paste();
+ Assert.AreEqual(innerGrid.ContentProperty.CollectionElements[3], selection.PrimarySelection);
+
+ selection.SetSelectedComponents(new[] {innerGrid});
+ xamlContext.XamlEditAction.Paste();
+ Assert.AreEqual(innerGrid.ContentProperty.CollectionElements[4], selection.PrimarySelection);
+
+ Assert.IsNullOrEmpty(innerGrid.ContentProperty.CollectionElements[0].Name);
+ Assert.AreEqual(_name, innerGrid.ContentProperty.CollectionElements[1].Name);
+ Assert.AreEqual(_name + "_Copy", innerGrid.ContentProperty.CollectionElements[2].Name);
+ Assert.AreEqual(_name + "_Copy1", innerGrid.ContentProperty.CollectionElements[3].Name);
+ Assert.AreEqual(_name + "_Copy2", innerGrid.ContentProperty.CollectionElements[4].Name);
+
+ xamlContext.XamlEditAction.Copy(new[] {innerGrid.ContentProperty.CollectionElements[3]});
+ var cutXaml = Clipboard.GetText(TextDataFormat.Xaml);
+ Assert.That(cutXaml, Is.StringContaining(":Name=\"" + _name + "_Copy1\""));
+
+ selection.SetSelectedComponents(new[] {innerGrid});
+ xamlContext.XamlEditAction.Paste();
+ Assert.AreEqual(innerGrid.ContentProperty.CollectionElements[5], selection.PrimarySelection);
+ Assert.AreEqual(_name + "_Copy3", innerGrid.ContentProperty.CollectionElements[5].Name);
+
+ var gridDepObj = grid.Component as DependencyObject;
+ Assert.IsNotNull(gridDepObj);
+ var nameScope = NameScope.GetNameScope(gridDepObj);
+ Assert.IsNotNull(nameScope);
+ Assert.IsNotNull(nameScope.FindName(_name));
+ Assert.IsNotNull(nameScope.FindName(_name + "_Copy"));
+ Assert.IsNotNull(nameScope.FindName(_name + "_Copy1"));
+ Assert.IsNotNull(nameScope.FindName(_name + "_Copy2"));
+ Assert.IsNotNull(nameScope.FindName(_name + "_Copy3"));
+ Assert.IsNull(nameScope.FindName(_name + "_Copy4"));
+ }
}
}
diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/NameScopeHelper.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/NameScopeHelper.cs
index aac3da5257..d77f74961e 100644
--- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/NameScopeHelper.cs
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/NameScopeHelper.cs
@@ -10,7 +10,7 @@ namespace ICSharpCode.WpfDesign.XamlDom
///
/// Static methods to help with operations on Xaml elements.
///
- internal static class NameScopeHelper
+ public static class NameScopeHelper
{
///
/// Finds the XAML namescope for the specified object and uses it to unregister the old name and then register the new name.
@@ -18,16 +18,11 @@ namespace ICSharpCode.WpfDesign.XamlDom
/// The object where the name was changed.
/// The old name.
/// The new name.
- public static void NameChanged(XamlObject namedObject, string oldName, string newName)
+ internal static void NameChanged(XamlObject namedObject, string oldName, string newName)
{
var obj = namedObject;
while (obj != null) {
- var nameScope = obj.Instance as INameScope;
- if (nameScope == null) {
- var depObj = obj.Instance as DependencyObject;
- if (depObj != null)
- nameScope = NameScope.GetNameScope(depObj);
- }
+ var nameScope = GetNameScopeFromObject(obj.Instance);
if (nameScope != null) {
if (oldName != null) {
try {
@@ -52,5 +47,33 @@ namespace ICSharpCode.WpfDesign.XamlDom
obj = obj.ParentObject;
}
}
+
+ ///
+ /// Gets the XAML namescope for the specified object.
+ ///
+ /// The object to get the XAML namescope for.
+ /// A XAML namescope, as an instance.
+ public static INameScope GetNameScopeFromObject(object obj)
+ {
+ var nameScope = obj as INameScope;
+ if (nameScope == null) {
+ var depObj = obj as DependencyObject;
+ if (depObj != null)
+ nameScope = NameScope.GetNameScope(depObj);
+ }
+
+ return nameScope;
+ }
+
+ ///
+ /// Clears the if the object is a .
+ ///
+ /// The object to clear the on.
+ public static void ClearNameScopeProperty(object obj)
+ {
+ var depObj = obj as DependencyObject;
+ if (depObj != null)
+ depObj.ClearValue(NameScope.NameScopeProperty);
+ }
}
}