Last active
August 29, 2015 14:18
-
-
Save aloisdeniel/463440031a20f6f5e1e1 to your computer and use it in GitHub Desktop.
Cloning all dependency properties of a UserControl
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace App1 | |
{ | |
using System; | |
using System.Linq; | |
using Windows.UI.Xaml.Controls; | |
using System.Reflection; | |
using Windows.UI.Xaml; | |
using System.Collections.Generic; | |
public static class UserControlExtensions | |
{ | |
const string dpSuffix = "Property"; | |
/// <summary> | |
/// Instanciates a user control of the same type and copies all its dependency properties. | |
/// </summary> | |
/// <param name="control">The user control</param> | |
/// <returns>Rreturns a new instance of the given user control type with same dependency properties values.</returns> | |
public static UserControl Clone(this UserControl control) | |
{ | |
var clone = (UserControl)Activator.CreateInstance(control.GetType()); | |
Clone(control, clone); | |
return clone; | |
} | |
/// <summary> | |
/// Copies all the dependency properties of the user control into other control. | |
/// </summary> | |
/// <param name="control">The user control</param> | |
/// <param name="clone">The cloned user control</param> | |
public static void Clone(this UserControl control, UserControl clone) | |
{ | |
foreach (var dp in GetDependencyProperties(control.GetType())) | |
{ | |
var value = dp.GetMethod.Invoke(control, new object[0]); | |
if (dp.SetMethod != null && dp.SetMethod.IsPublic) | |
{ | |
try | |
{ | |
// Set method throws an exception on "Content" and "Template" | |
dp.SetMethod.Invoke(clone, new object[] { value }); | |
} | |
catch { } | |
} | |
} | |
} | |
/// <summary> | |
/// Gets all dependency properties of an object type. | |
/// </summary> | |
/// <param name="t">The type of the object</param> | |
/// <returns>A collection of property info.</returns> | |
public static IEnumerable<PropertyInfo> GetDependencyProperties(Type t) | |
{ | |
var result = new List<PropertyInfo>(); | |
// 1. We need to scan base type in order to get static properties. | |
var baseType = t.GetTypeInfo().BaseType; | |
if (baseType != null) | |
{ | |
result.AddRange(GetDependencyProperties(baseType)); | |
} | |
var runtimefields = t.GetRuntimeFields(); | |
var runtimeprops = t.GetRuntimeProperties(); | |
var dps = runtimeprops.Where((p) => | |
p.SetMethod != null && p.SetMethod.IsPublic && | |
p.GetMethod != null && p.GetMethod.IsPublic && | |
(runtimeprops.Any((p2) => (p2.PropertyType == typeof(DependencyProperty) && (p.Name + dpSuffix) == p2.Name)) || | |
runtimefields.Any((p2) => p2.IsPublic && p2.IsStatic && p2.FieldType == typeof(DependencyProperty) && (p.Name + dpSuffix) == p2.Name))); | |
result.AddRange(dps); | |
return result; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment