-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathStyleBehavior.cs
89 lines (77 loc) · 4.4 KB
/
StyleBehavior.cs
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
using System;
using System.Windows;
using Meowtrix.Linq;
namespace Meowtrix.WPF.Extend
{
public static class StyleBehavior
{
public static Style Merge(params Style[] styles)
{
var newstyle = new Style();
foreach (var style in styles)
{
if (newstyle.TargetType == null) newstyle.TargetType = style.TargetType;
else if (newstyle.TargetType.IsAssignableFrom(style.TargetType)) newstyle.TargetType = style.TargetType;
else if (!style.TargetType.IsAssignableFrom(newstyle.TargetType)) throw new ArgumentException("Styles must target to same derived type");
newstyle.Triggers.AddRange(style.Triggers);
newstyle.Setters.AddRange(style.Setters);
newstyle.Resources.MergedDictionaries.Add(style.Resources);
}
newstyle.Seal();
return newstyle;
}
public static object GetDynamicBaseStyle(FrameworkElement obj) => (object)obj.GetValue(DynamicBaseStyleProperty);
public static void SetDynamicBaseStyle(FrameworkElement obj, object value) => obj.SetValue(DynamicBaseStyleProperty, value);
// Using a DependencyProperty as the backing store for DynamicBaseStyle. This enables animation, styling, binding, etc...
public static readonly DependencyProperty DynamicBaseStyleProperty =
DependencyProperty.RegisterAttached("DynamicBaseStyle", typeof(object), typeof(StyleBehavior), new PropertyMetadata(null, OnDynamicBaseStyleChanged));
private static void OnDynamicBaseStyleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (e.OldValue == e.NewValue) return;
var c = d as FrameworkElement;
if (c == null) throw new NotSupportedException("DynamicBaseStyle is only available on FrameworkElement");
var key = e.NewValue;
if (key != null)
c.SetResourceReference(BasedOnStyleProperty, key);
else
c.ClearValue(BasedOnStyleProperty);
}
public static Style GetBasedOnStyle(FrameworkElement obj) => (Style)obj.GetValue(BasedOnStyleProperty);
public static void SetBasedOnStyle(FrameworkElement obj, Style value) => obj.SetValue(BasedOnStyleProperty, value);
// Using a DependencyProperty as the backing store for BasedOnStyle. This enables animation, styling, binding, etc...
public static readonly DependencyProperty BasedOnStyleProperty =
DependencyProperty.RegisterAttached("BasedOnStyle", typeof(Style), typeof(StyleBehavior), new PropertyMetadata(null, OnBasedOnStyleChanged));
private static void OnBasedOnStyleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (e.OldValue == e.NewValue) return;
FrameworkElement c = d as FrameworkElement;
if (c == null) throw new NotSupportedException("DynamicBaseStyle is only available on FrameworkElement");
var baseStyle = e.NewValue as Style;
var originalStyle = GetOriginalStyle(c);
if (originalStyle == null)
{
originalStyle = c.Style;
if (originalStyle == null)//implicit style
{
for (var type = c.GetType(); type != null; type = type.BaseType)
{
originalStyle = c.TryFindResource(type) as Style;
if (originalStyle != null) break;
}
if (originalStyle == null)//no default style
{
c.Style = baseStyle;
return;
}
}
SetOriginalStyle(c, originalStyle);
}
c.Style = Merge(baseStyle, originalStyle);
}
public static Style GetOriginalStyle(FrameworkElement obj) => (Style)obj.GetValue(OriginalStyleProperty);
public static void SetOriginalStyle(FrameworkElement obj, Style value) => obj.SetValue(OriginalStyleProperty, value);
// Using a DependencyProperty as the backing store for OriginalStyle. This enables animation, styling, binding, etc...
public static readonly DependencyProperty OriginalStyleProperty =
DependencyProperty.RegisterAttached("OriginalStyle", typeof(Style), typeof(StyleBehavior), new PropertyMetadata(null));
}
}