如何在WinRT XAML C#中克隆UIElement?

我首先尝试了这种方法,但得到错误“元素已经是另一个元素的孩子”

var objClone = new MyImageControl(); objClone = this; ((Canvas)this.Parent).Children.Add(objClone); 

然后我检查了这个 ,但是在WinRT中没有XamlWriter和XamlReader。 我试图使用MemberwiseClone()但它抛出exception,“不能使用已与其基础RCW分离的COM对象System.Runtime.InteropServices.InvalidComObjectException ”。 那么有谁能告诉我如何将canvas中的现有UserControl克隆到自身?

我编写了一个UIElement扩展,用于复制元素的属性和子元素 – 请注意,它不会为克隆设置事件。

 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Windows.UI.Xaml; using System.Reflection; using Windows.UI.Xaml.Controls; namespace UIElementClone { public static class UIElementExtensions { public static T DeepClone(this T source) where T : UIElement { T result; // Get the type Type type = source.GetType(); // Create an instance result = Activator.CreateInstance(type) as T; CopyProperties(source, result, type); DeepCopyChildren(source, result); return result; } private static void DeepCopyChildren(T source, T result) where T : UIElement { // Deep copy children. Panel sourcePanel = source as Panel; if (sourcePanel != null) { Panel resultPanel = result as Panel; if (resultPanel != null) { foreach (UIElement child in sourcePanel.Children) { // RECURSION! UIElement childClone = DeepClone(child); resultPanel.Children.Add(childClone); } } } } private static void CopyProperties(T source, T result, Type type) where T : UIElement { // Copy all properties. IEnumerable properties = type.GetRuntimeProperties(); foreach (var property in properties) { if (property.Name != "Name") // do not copy names or we cannot add the clone to the same parent as the original. { if ((property.CanWrite) && (property.CanRead)) { object sourceProperty = property.GetValue(source); UIElement element = sourceProperty as UIElement; if (element != null) { UIElement propertyClone = element.DeepClone(); property.SetValue(result, propertyClone); } else { try { property.SetValue(result, sourceProperty); } catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex); } } } } } } } } 

如果您发现它有用,请随意使用此代码。

您可以尝试使用XamlWriter和XamlReader之外的序列化程序来实现链接所描述的相同效果。 例如,使用ServiceStack.Text将JSON序列化为字符串,然后从该字符串中获取新对象并将其添加到父对象。