/// <summary> /// Creates a new instance of the same type and copies all properties and values. /// </summary> /// <typeparam name="T">A type that extends DependencyObject</typeparam> /// <param name="source"></param> /// <returns>A new instance that represents a copy of the properties and values of the original instance.</returns> public static T Clone <T>(this T source) where T : DependencyObject { Type t = source.GetType(); T no = (T)Activator.CreateInstance(t); Type wt = t; while (wt.BaseType != typeof(DependencyObject)) { FieldInfo[] fi = wt.GetFields(BindingFlags.Static | BindingFlags.Public); for (int i = 0; i < fi.Length; i++) { { DependencyProperty dp = fi[i].GetValue(source) as DependencyProperty; if (dp != null && fi[i].Name != "NameProperty") { DependencyObject obj = source.GetValue(dp) as DependencyObject; if (obj != null) { object o = obj.Clone(); no.SetValue(dp, o); } else { if (fi[i].Name != "CountProperty" && fi[i].Name != "GeometryTransformProperty" && fi[i].Name != "ActualWidthProperty" && fi[i].Name != "ActualHeightProperty" && fi[i].Name != "MaxWidthProperty" && fi[i].Name != "MaxHeightProperty" && fi[i].Name != "StyleProperty") { no.SetValue(dp, source.GetValue(dp)); } } } } } wt = wt.BaseType; } PropertyInfo[] pis = t.GetProperties(); for (int i = 0; i < pis.Length; i++) { if ( pis[i].Name != "Name" && pis[i].Name != "Parent" && pis[i].Name != "TargetType" && pis[i].CanRead && pis[i].CanWrite && !pis[i].PropertyType.IsArray && !pis[i].PropertyType.IsSubclassOf(typeof(DependencyObject)) && pis[i].GetIndexParameters().Length == 0 && pis[i].GetValue(source, null) != null && pis[i].GetValue(source, null) != (object)default(int) && pis[i].GetValue(source, null) != (object)default(double) && pis[i].GetValue(source, null) != (object)default(float) ) { pis[i].SetValue(no, pis[i].GetValue(source, null), null); } else if (pis[i].PropertyType.GetInterface("IList", true) != null) { int cnt = (int)pis[i].PropertyType.InvokeMember("get_Count", BindingFlags.InvokeMethod, null, pis[i].GetValue(source, null), null); for (int c = 0; c < cnt; c++) { object val = pis[i].PropertyType.InvokeMember("get_Item", BindingFlags.InvokeMethod, null, pis[i].GetValue(source, null), new object[] { c }); object nVal = val; DependencyObject v = val as DependencyObject; if (v != null) { nVal = v.Clone(); } if (pis[i].GetValue(no, null) == null) { object obj = Activator.CreateInstance(pis[i].PropertyType); pis[i].SetValue(no, obj, null); } pis[i].PropertyType.InvokeMember("Add", BindingFlags.InvokeMethod, null, pis[i].GetValue(no, null), new object[] { nVal }); } } } return(no); }