[英]How to clone UIElement in WinRT XAML C#?
我首先尝试了这种方法,但得到错误“元素已经是另一个元素的孩子”
var objClone = new MyImageControl();
objClone = this;
((Canvas)this.Parent).Children.Add(objClone);
然后我检查这个和这个 ,但的XamlWriter和XamlReader不可在WinRT中。 我试图使用MemberwiseClone()但它抛出异常,“不能使用已与其底层RCW分离的COM对象System.Runtime.InteropServices.InvalidComObjectException
”。 那么有谁能告诉我如何将画布中的现有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<T>(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<T>(source, result, type);
DeepCopyChildren<T>(source, result);
return result;
}
private static void DeepCopyChildren<T>(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>(T source, T result, Type type) where T : UIElement
{
// Copy all properties.
IEnumerable<PropertyInfo> 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序列化为字符串,然后从该字符串中获取新对象并将其添加到父对象。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.