2 using System.Collections.Generic;
3 using System.Reflection;
4 using Tizen.NUI.StyleSheets;
5 using System.ComponentModel;
7 namespace Tizen.NUI.Binding
9 [ContentProperty("Setters")]
10 internal sealed class Style : IStyle
12 internal const string StyleClassPrefix = "Tizen.NUI.Binding.StyleClass.";
14 readonly BindableProperty _basedOnResourceProperty = BindableProperty.CreateAttached("BasedOnResource", typeof(Style), typeof(Style), default(Style),
15 propertyChanged: OnBasedOnResourceChanged);
17 readonly List<WeakReference<BindableObject>> _targets = new List<WeakReference<BindableObject>>(4);
21 string _baseResourceKey;
23 IList<Behavior> _behaviors;
25 IList<TriggerBase> _triggers;
27 public Style([TypeConverter(typeof(TypeTypeConverter))] [Parameter("TargetType")] Type targetType)
29 if (targetType == null)
30 throw new ArgumentNullException("targetType");
32 TargetType = targetType;
33 Setters = new List<Setter>();
36 public bool ApplyToDerivedTypes { get; set; }
40 get { return _basedOnStyle; }
43 if (_basedOnStyle == value)
45 if (!ValidateBasedOn(value))
46 throw new ArgumentException("BasedOn.TargetType is not compatible with TargetType");
47 Style oldValue = _basedOnStyle;
48 _basedOnStyle = value;
49 BasedOnChanged(oldValue, value);
51 BaseResourceKey = null;
55 public string BaseResourceKey
57 get { return _baseResourceKey; }
60 if (_baseResourceKey == value)
62 _baseResourceKey = value;
63 //update all DynamicResources
64 foreach (WeakReference<BindableObject> bindableWr in _targets)
66 BindableObject target;
67 if (!bindableWr.TryGetTarget(out target))
69 target.RemoveDynamicResource(_basedOnResourceProperty);
71 target.SetDynamicResource(_basedOnResourceProperty, value);
78 internal IList<Behavior> Behaviors
80 get { return _behaviors ?? (_behaviors = new AttachedCollection<Behavior>()); }
83 public bool CanCascade { get; set; }
85 public string Class { get; set; }
87 public IList<Setter> Setters { get; }
89 /// This will be public opened in tizen_next after ACR done. Before ACR, need to be hidden as inhouse API.
90 [EditorBrowsable(EditorBrowsableState.Never)]
91 public IList<TriggerBase> Triggers
93 get { return _triggers ?? (_triggers = new AttachedCollection<TriggerBase>()); }
96 void IStyle.Apply(BindableObject bindable)
98 _targets.Add(new WeakReference<BindableObject>(bindable));
99 if (BaseResourceKey != null)
100 bindable.SetDynamicResource(_basedOnResourceProperty, BaseResourceKey);
101 ApplyCore(bindable, BasedOn ?? GetBasedOnResource(bindable));
104 public Type TargetType { get; }
106 void IStyle.UnApply(BindableObject bindable)
108 UnApplyCore(bindable, BasedOn ?? GetBasedOnResource(bindable));
109 bindable.RemoveDynamicResource(_basedOnResourceProperty);
110 _targets.RemoveAll(wr =>
112 BindableObject target;
113 return wr.TryGetTarget(out target) && target == bindable;
117 internal bool CanBeAppliedTo(Type targetType)
119 if (TargetType == targetType)
121 if (!ApplyToDerivedTypes)
125 targetType = targetType.GetTypeInfo().BaseType;
126 if (TargetType == targetType)
128 } while (targetType != typeof(Element));
132 void ApplyCore(BindableObject bindable, Style basedOn)
135 ((IStyle)basedOn).Apply(bindable);
137 foreach (Setter setter in Setters)
138 setter.Apply(bindable, true);
139 ((AttachedCollection<Behavior>)Behaviors).AttachTo(bindable);
140 ((AttachedCollection<TriggerBase>)Triggers).AttachTo(bindable);
143 void BasedOnChanged(Style oldValue, Style newValue)
145 foreach (WeakReference<BindableObject> bindableRef in _targets)
147 BindableObject bindable;
148 if (!bindableRef.TryGetTarget(out bindable))
151 UnApplyCore(bindable, oldValue);
152 ApplyCore(bindable, newValue);
156 Style GetBasedOnResource(BindableObject bindable)
158 return (Style)bindable.GetValue(_basedOnResourceProperty);
161 static void OnBasedOnResourceChanged(BindableObject bindable, object oldValue, object newValue)
163 // Style style = (bindable as /*VisualElement*/BaseHandle).Style;
164 // if (style == null)
166 // style.UnApplyCore(bindable, (Style)oldValue);
167 // style.ApplyCore(bindable, (Style)newValue);
170 void UnApplyCore(BindableObject bindable, Style basedOn)
172 ((AttachedCollection<TriggerBase>)Triggers).DetachFrom(bindable);
173 ((AttachedCollection<Behavior>)Behaviors).DetachFrom(bindable);
174 foreach (Setter setter in Setters)
175 setter.UnApply(bindable, true);
178 ((IStyle)basedOn).UnApply(bindable);
181 bool ValidateBasedOn(Style value)
185 return value.TargetType.IsAssignableFrom(TargetType);