我已经使用canvas动态创建了一个customcontrol。我需要将其转换为图像。由于画布未添加到xaml中,因此我将其添加到rootgrid并转换为图像然后将其删除。为了避免添加和删除视图时出现视觉延迟,我尝试使用反射克隆视图,但无法复制元素的所有属性。在克隆属性时会遇到Stackoverflow异常
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.GetProperties();
foreach (var property in properties)
{
Type types = property.GetType();
if (property.Name != "Name" && property.Name!="Resources" ) // do not copy names or we cannot add the clone to the same parent as the original.
{
try
{
if ((property.CanWrite) && (property.CanRead) )
{
object sourceProperty = property.GetValue(source,null);
UIElement element = sourceProperty as UIElement;
if (element != null)
{
UIElement propertyClone = element.DeepClone();
property.SetValue(result, propertyClone);
}
else
{
try
{
// if (property.GetIndexParameters().Any())
{
MethodInfo mi = property.GetSetMethod(true);
if (mi != null)
{
property.SetValue(result, sourceProperty, null);
}
}
}
catch (Exception)
{
}
}
}
}
catch(Exception e)
{
}
}
}
}