如何克隆的UIElement中的WinRT XAML C#? [英] How to clone UIElement in WinRT XAML C#?

查看:153
本文介绍了如何克隆的UIElement中的WinRT XAML C#?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我第一次尝试这种做法,但得到的错误元素已经是另一个元素的子元素

I have tried this approach first but getting error "Element is already the child of another element"

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



然后我检查的this 并的这个,但和的XamlWriter XamlReader不提供WinRT的。我曾尝试使用 MemberwiseClone() 但它抛出异常,不能用已从其基础RCW分开COM对象。 System.Runtime.InteropServices.InvalidComObjectException 。因此,谁能告诉我怎么可以复制我的画布现有的用户控件本身?

Then I checked this and this, but XamlWriter and XamlReader is not available in WinRT. I have tried to use MemberwiseClone() but it throws exception, "COM object that has been separated from its underlying RCW cannot be used. System.Runtime.InteropServices.InvalidComObjectException". So can anyone tell me how can I clone the existing UserControl in my canvas to itself ?

推荐答案

我已经写了的UIElement 扩展,副本的属性和元素的儿童 - 请注意,它的不可以设置为克隆的事件

I have written a UIElement extension that copies the properties and children of an element -- note that it does not set up an events for the clone.

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);
                            }
                        }
                    }
                }
            }
        }        
    }
}

随意,如果你觉得它有用使用此代码。

Feel free to use this code if you find it useful.

这篇关于如何克隆的UIElement中的WinRT XAML C#?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆