1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
|
using System;
using System.Linq;
using System.Reflection;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media;
using WBinding = Windows.UI.Xaml.Data.Binding;
using WBindingExpression = Windows.UI.Xaml.Data.BindingExpression;
#if WINDOWS_UWP
namespace Xamarin.Forms.Platform.UWP
#else
namespace Xamarin.Forms.Platform.WinRT
#endif
{
internal static class FrameworkElementExtensions
{
static readonly Lazy<ConcurrentDictionary<Type, DependencyProperty>> ForegroundProperties =
new Lazy<ConcurrentDictionary<Type, DependencyProperty>>(() => new ConcurrentDictionary<Type, DependencyProperty>());
public static Brush GetForeground(this FrameworkElement element)
{
if (element == null)
throw new ArgumentNullException("element");
return (Brush)element.GetValue(GetForegroundProperty(element));
}
public static WBinding GetForegroundBinding(this FrameworkElement element)
{
WBindingExpression expr = element.GetBindingExpression(GetForegroundProperty(element));
if (expr == null)
return null;
return expr.ParentBinding;
}
public static object GetForegroundCache(this FrameworkElement element)
{
WBinding binding = GetForegroundBinding(element);
if (binding != null)
return binding;
return GetForeground(element);
}
public static void RestoreForegroundCache(this FrameworkElement element, object cache)
{
var binding = cache as WBinding;
if (binding != null)
SetForeground(element, binding);
else
SetForeground(element, (Brush)cache);
}
public static void SetForeground(this FrameworkElement element, Brush foregroundBrush)
{
if (element == null)
throw new ArgumentNullException("element");
element.SetValue(GetForegroundProperty(element), foregroundBrush);
}
public static void SetForeground(this FrameworkElement element, WBinding binding)
{
if (element == null)
throw new ArgumentNullException("element");
element.SetBinding(GetForegroundProperty(element), binding);
}
internal static T GetFirstDescendant<T>(this DependencyObject element) where T : FrameworkElement
{
int count = VisualTreeHelper.GetChildrenCount(element);
for (var i = 0; i < count; i++)
{
DependencyObject child = VisualTreeHelper.GetChild(element, i);
T target = child as T ?? GetFirstDescendant<T>(child);
if (target != null)
return target;
}
return null;
}
static DependencyProperty GetForegroundProperty(FrameworkElement element)
{
if (element is Control)
return Control.ForegroundProperty;
if (element is TextBlock)
return TextBlock.ForegroundProperty;
Type type = element.GetType();
DependencyProperty foregroundProperty;
if (!ForegroundProperties.Value.TryGetValue(type, out foregroundProperty))
{
FieldInfo field = type.GetFields().FirstOrDefault(f => f.Name == "ForegroundProperty");
if (field == null)
throw new ArgumentException("type is not a Foregroundable type");
var property = (DependencyProperty)field.GetValue(null);
ForegroundProperties.Value.TryAdd(type, property);
return property;
}
return foregroundProperty;
}
}
}
|