2 using System.Collections.Generic;
3 using System.ComponentModel;
4 using System.Diagnostics;
5 using System.Reflection;
6 using System.Runtime.CompilerServices;
7 using Tizen.NUI.Binding.Internals;
9 namespace Tizen.NUI.Binding
12 /// Provides a mechanism by which application developers can propagate changes that are made to data in one object to another, by enabling validation, type coercion, and an event system.
14 [EditorBrowsable(EditorBrowsableState.Never)]
15 public abstract class BindableObject : INotifyPropertyChanged, IDynamicResourceHandler
18 /// Implements the bound property whose interface is provided by the BindingContext property.
20 [EditorBrowsable(EditorBrowsableState.Never)]
21 public static readonly BindableProperty BindingContextProperty =
22 BindableProperty.Create("BindingContext", typeof(object), typeof(BindableObject), default(object),
23 BindingMode.OneWay, null, BindingContextPropertyChanged, null, null, BindingContextPropertyBindingChanging);
25 readonly List<BindablePropertyContext> _properties = new List<BindablePropertyContext>(4);
28 object _inheritedContext;
31 /// Gets or sets object that contains the properties that will be targeted by the bound properties that belong to this BindableObject.
33 /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
34 [EditorBrowsable(EditorBrowsableState.Never)]
35 public object BindingContext
37 get { return _inheritedContext ?? GetValue(BindingContextProperty); }
38 set { SetValue(BindingContextProperty, value); }
41 void IDynamicResourceHandler.SetDynamicResource(BindableProperty property, string key)
43 SetDynamicResource(property, key, false);
47 /// Raised when a property has changed.
49 /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
50 [EditorBrowsable(EditorBrowsableState.Never)]
51 public event PropertyChangedEventHandler PropertyChanged;
54 /// Raised whenever the BindingContext property changes.
56 /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
57 [EditorBrowsable(EditorBrowsableState.Never)]
58 public event EventHandler BindingContextChanged;
60 internal void ClearValue(BindableProperty property, bool fromStyle)
62 ClearValue(property, fromStyle: fromStyle, checkAccess: true);
66 /// Clears any value set by Tizen.NUI.Xaml.BindableObject.SetValue.
68 /// <param name="property">The BindableProperty to clear</param>
69 internal void ClearValue(BindableProperty property)
71 ClearValue(property, fromStyle: false, checkAccess: true);
75 /// Clears any value set by Tizen.NUI.Xaml.BindableObject.SetValue for the property that is identified by propertyKey.
77 /// <param name="propertyKey">The BindablePropertyKey that identifies the BindableProperty to clear.</param>
78 internal void ClearValue(BindablePropertyKey propertyKey)
80 if (propertyKey == null)
81 throw new ArgumentNullException("propertyKey");
83 ClearValue(propertyKey.BindableProperty, fromStyle:false, checkAccess: false);
87 /// Return true if the target property exists and has been set.
89 /// <param name="targetProperty">The target property</param>
90 /// <returns>return true if the target property exists and has been set</returns>
91 internal bool IsSet(BindableProperty targetProperty)
93 if (targetProperty == null)
94 throw new ArgumentNullException(nameof(targetProperty));
96 var bpcontext = GetContext(targetProperty);
97 return bpcontext != null
98 && (bpcontext.Attributes & BindableContextAttributes.IsDefaultValue) == 0;
102 /// Returns the value that is contained the BindableProperty.
104 /// <param name="property">The BindableProperty for which to get the value.</param>
105 /// <returns>The value that is contained the BindableProperty</returns>
106 /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
107 [EditorBrowsable(EditorBrowsableState.Never)]
108 public object GetValue(BindableProperty property)
110 if (property == null)
111 throw new ArgumentNullException("property");
113 BindablePropertyContext context = property.DefaultValueCreator != null ? GetOrCreateContext(property) : GetContext(property);
116 return property.DefaultValue;
118 return context.Value;
122 /// Raised when a property is about to change.
124 /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
125 [EditorBrowsable(EditorBrowsableState.Never)]
126 public event PropertyChangingEventHandler PropertyChanging;
129 /// Removes a previously set binding.
131 /// <param name="property">The BindableProperty from which to remove bindings.</param>
132 internal void RemoveBinding(BindableProperty property)
134 if (property == null)
135 throw new ArgumentNullException("property");
137 BindablePropertyContext context = GetContext(property);
138 if (context == null || context.Binding == null)
141 RemoveBinding(property, context);
145 /// Assigns a binding to a property.
147 /// <param name="targetProperty">The BindableProperty on which to set a binding.</param>
148 /// <param name="binding">The binding to set.</param>
149 /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
150 [EditorBrowsable(EditorBrowsableState.Never)]
151 public void SetBinding(BindableProperty targetProperty, BindingBase binding)
153 SetBinding(targetProperty, binding, false);
156 private bool isCreateByXaml = false;
157 /// Only used by the IL of xaml, will never changed to not hidden.
158 [EditorBrowsable(EditorBrowsableState.Never)]
159 public virtual bool IsCreateByXaml
163 return isCreateByXaml;
167 isCreateByXaml = value;
172 /// Sets the value of the specified property.
174 /// <param name="property">The BindableProperty on which to assign a value.</param>
175 /// <param name="value">The value to set.</param>
176 /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
177 [EditorBrowsable(EditorBrowsableState.Never)]
178 public void SetValue(BindableProperty property, object value)
180 if (true == isCreateByXaml)
182 SetValue(property, value, false, true);
186 property.PropertyChanged?.Invoke(this, null, value);
190 internal void SetValueAndForceSendChangeSignal(BindableProperty property, object value)
192 if (property == null)
193 throw new ArgumentNullException("property");
195 if (true == isCreateByXaml)
197 if (property.IsReadOnly)
198 throw new InvalidOperationException(string.Format("The BindableProperty \"{0}\" is readonly.", property.PropertyName));
200 SetValueCore(property, value, SetValueFlags.ClearOneWayBindings | SetValueFlags.ClearDynamicResource,
201 SetValuePrivateFlags.ManuallySet | SetValuePrivateFlags.CheckAccess, true);
205 property.PropertyChanged?.Invoke(this, null, value);
210 /// Sets the value of the propertyKey.
212 /// <param name="propertyKey">The BindablePropertyKey on which to assign a value.</param>
213 /// <param name="value">The value to set.</param>
214 /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
215 [EditorBrowsable(EditorBrowsableState.Never)]
216 public void SetValue(BindablePropertyKey propertyKey, object value)
218 if (propertyKey == null)
219 throw new ArgumentNullException("propertyKey");
221 SetValue(propertyKey.BindableProperty, value, false, false);
225 /// Set the inherited context to a neated element.
227 /// <param name="bindable">The object on which to set the inherited binding context.</param>
228 /// <param name="value">The inherited context to set.</param>
229 [EditorBrowsable(EditorBrowsableState.Never)]
230 public static void SetInheritedBindingContext(BindableObject bindable, object value)
232 BindablePropertyContext bpContext = bindable.GetContext(BindingContextProperty);
233 if (bpContext != null && ((bpContext.Attributes & BindableContextAttributes.IsManuallySet) != 0))
236 object oldContext = bindable._inheritedContext;
238 if (ReferenceEquals(oldContext, value))
241 if (bpContext != null && oldContext == null)
242 oldContext = bpContext.Value;
244 if (bpContext != null && bpContext.Binding != null)
246 bpContext.Binding.Context = value;
247 bindable._inheritedContext = null;
251 bindable._inheritedContext = value;
254 bindable.ApplyBindings(skipBindingContext:false, fromBindingContextChanged:true);
255 bindable.OnBindingContextChanged();
259 /// Apply the bindings to BindingContext.
261 /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
262 [EditorBrowsable(EditorBrowsableState.Never)]
263 protected void ApplyBindings()
265 ApplyBindings(skipBindingContext: false, fromBindingContextChanged: false);
269 /// Override this method to execute an action when the BindingContext changes.
271 /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
272 [EditorBrowsable(EditorBrowsableState.Never)]
273 protected virtual void OnBindingContextChanged()
275 BindingContextChanged?.Invoke(this, EventArgs.Empty);
279 /// Call this method from a child class to notify that a change happened on a property.
281 /// <param name="propertyName">The name of the property that changed.</param>
282 /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
283 [EditorBrowsable(EditorBrowsableState.Never)]
284 protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
285 => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
288 /// Call this method from a child class to notify that a change is going to happen on a property.
290 /// <param name="propertyName">The name of the property that is changing.</param>
291 /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
292 [EditorBrowsable(EditorBrowsableState.Never)]
293 protected virtual void OnPropertyChanging([CallerMemberName] string propertyName = null)
294 => PropertyChanging?.Invoke(this, new PropertyChangingEventArgs(propertyName));
297 /// Unapplies all previously set bindings.
299 /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
300 [EditorBrowsable(EditorBrowsableState.Never)]
301 protected void UnapplyBindings()
303 for (int i = 0, _propertiesCount = _properties.Count; i < _propertiesCount; i++) {
304 BindablePropertyContext context = _properties [i];
305 if (context.Binding == null)
308 context.Binding.Unapply();
312 internal bool GetIsBound(BindableProperty targetProperty)
314 if (targetProperty == null)
315 throw new ArgumentNullException("targetProperty");
317 BindablePropertyContext bpcontext = GetContext(targetProperty);
318 return bpcontext != null && bpcontext.Binding != null;
322 /// Returns the value that is contained the BindableProperty.
324 /// <param name="property0">The BindableProperty instance.</param>
325 /// <param name="property1">The BindableProperty instance.</param>
326 /// <returns>The value that is contained the BindableProperty</returns>
327 internal object[] GetValues(BindableProperty property0, BindableProperty property1)
329 var values = new object[2];
331 for (var i = 0; i < _properties.Count; i++)
333 BindablePropertyContext context = _properties[i];
335 if (ReferenceEquals(context.Property, property0))
337 values[0] = context.Value;
340 else if (ReferenceEquals(context.Property, property1))
342 values[1] = context.Value;
346 if (property0 == null && property1 == null)
350 if (!ReferenceEquals(property0, null))
351 values[0] = property0.DefaultValueCreator == null ? property0.DefaultValue : CreateAndAddContext(property0).Value;
352 if (!ReferenceEquals(property1, null))
353 values[1] = property1.DefaultValueCreator == null ? property1.DefaultValue : CreateAndAddContext(property1).Value;
359 /// Returns the value that is contained the BindableProperty.
361 /// <param name="property0">The BindableProperty instance.</param>
362 /// <param name="property1">The BindableProperty instance.</param>
363 /// <param name="property2">The BindableProperty instance.</param>
364 /// <returns>The value that is contained the BindableProperty</returns>
365 internal object[] GetValues(BindableProperty property0, BindableProperty property1, BindableProperty property2)
367 var values = new object[3];
369 for (var i = 0; i < _properties.Count; i++)
371 BindablePropertyContext context = _properties[i];
373 if (ReferenceEquals(context.Property, property0))
375 values[0] = context.Value;
378 else if (ReferenceEquals(context.Property, property1))
380 values[1] = context.Value;
383 else if (ReferenceEquals(context.Property, property2))
385 values[2] = context.Value;
389 if (property0 == null && property1 == null && property2 == null)
393 if (!ReferenceEquals(property0, null))
394 values[0] = property0.DefaultValueCreator == null ? property0.DefaultValue : CreateAndAddContext(property0).Value;
395 if (!ReferenceEquals(property1, null))
396 values[1] = property1.DefaultValueCreator == null ? property1.DefaultValue : CreateAndAddContext(property1).Value;
397 if (!ReferenceEquals(property2, null))
398 values[2] = property2.DefaultValueCreator == null ? property2.DefaultValue : CreateAndAddContext(property2).Value;
404 /// Returns the value that is contained the BindableProperty.
406 /// <param name="properties">The array of the BindableProperty instances</param>
407 /// <returns>The values that is contained the BindableProperty instances.</returns>
408 internal object[] GetValues(params BindableProperty[] properties)
410 var values = new object[properties.Length];
411 for (var i = 0; i < _properties.Count; i++) {
412 var context = _properties[i];
413 var index = properties.IndexOf(context.Property);
416 values[index] = context.Value;
418 for (var i = 0; i < values.Length; i++) {
419 if (!ReferenceEquals(values[i], null))
421 values[i] = properties[i].DefaultValueCreator == null ? properties[i].DefaultValue : CreateAndAddContext(properties[i]).Value;
426 internal virtual void OnRemoveDynamicResource(BindableProperty property)
430 internal virtual void OnSetDynamicResource(BindableProperty property, string key)
434 internal void RemoveDynamicResource(BindableProperty property)
436 if (property == null)
437 throw new ArgumentNullException("property");
439 OnRemoveDynamicResource(property);
440 BindablePropertyContext context = GetOrCreateContext(property);
441 context.Attributes &= ~BindableContextAttributes.IsDynamicResource;
444 internal void SetBinding(BindableProperty targetProperty, BindingBase binding, bool fromStyle)
446 if (targetProperty == null)
447 throw new ArgumentNullException("targetProperty");
449 throw new ArgumentNullException("binding");
451 if (fromStyle && !CanBeSetFromStyle(targetProperty))
454 var context = GetOrCreateContext(targetProperty);
456 context.Attributes |= BindableContextAttributes.IsSetFromStyle;
458 context.Attributes &= ~BindableContextAttributes.IsSetFromStyle;
460 if (context.Binding != null)
461 context.Binding.Unapply();
463 BindingBase oldBinding = context.Binding;
464 context.Binding = binding;
466 targetProperty.BindingChanging?.Invoke(this, oldBinding, binding);
468 binding.Apply(BindingContext, this, targetProperty);
471 bool CanBeSetFromStyle(BindableProperty property)
473 var context = GetContext(property);
476 if ((context.Attributes & BindableContextAttributes.IsSetFromStyle) == BindableContextAttributes.IsSetFromStyle)
478 if ((context.Attributes & BindableContextAttributes.IsDefaultValue) == BindableContextAttributes.IsDefaultValue)
480 if ((context.Attributes & BindableContextAttributes.IsDefaultValueCreated) == BindableContextAttributes.IsDefaultValueCreated)
485 internal void SetDynamicResource(BindableProperty property, string key)
487 SetDynamicResource(property, key, false);
490 internal void SetDynamicResource(BindableProperty property, string key, bool fromStyle)
492 if (property == null)
493 throw new ArgumentNullException(nameof(property));
494 if (string.IsNullOrEmpty(key))
495 throw new ArgumentNullException(nameof(key));
496 if (fromStyle && !CanBeSetFromStyle(property))
499 var context = GetOrCreateContext(property);
501 context.Attributes |= BindableContextAttributes.IsDynamicResource;
503 context.Attributes |= BindableContextAttributes.IsSetFromStyle;
505 context.Attributes &= ~BindableContextAttributes.IsSetFromStyle;
507 OnSetDynamicResource(property, key);
510 internal void SetValue(BindableProperty property, object value, bool fromStyle)
512 SetValue(property, value, fromStyle, true);
515 internal void SetValueCore(BindablePropertyKey propertyKey, object value, SetValueFlags attributes = SetValueFlags.None)
517 SetValueCore(propertyKey.BindableProperty, value, attributes, SetValuePrivateFlags.None, false);
521 /// For internal use.
523 /// <param name="property">The BindableProperty on which to assign a value.</param>
524 /// <param name="value">The value to set</param>
525 /// <param name="attributes">The set value flag</param>
526 [EditorBrowsable(EditorBrowsableState.Never)]
527 internal void SetValueCore(BindableProperty property, object value, SetValueFlags attributes = SetValueFlags.None)
529 SetValueCore(property, value, attributes, SetValuePrivateFlags.Default, false);
532 internal void SetValueCore(BindableProperty property, object value, SetValueFlags attributes, SetValuePrivateFlags privateAttributes, bool forceSendChangeSignal)
534 bool checkAccess = (privateAttributes & SetValuePrivateFlags.CheckAccess) != 0;
535 bool manuallySet = (privateAttributes & SetValuePrivateFlags.ManuallySet) != 0;
536 bool silent = (privateAttributes & SetValuePrivateFlags.Silent) != 0;
537 bool fromStyle = (privateAttributes & SetValuePrivateFlags.FromStyle) != 0;
538 bool converted = (privateAttributes & SetValuePrivateFlags.Converted) != 0;
540 if (property == null)
541 throw new ArgumentNullException("property");
542 if (checkAccess && property.IsReadOnly)
544 Debug.WriteLine("Can not set the BindableProperty \"{0}\" because it is readonly.", property.PropertyName);
548 if (!converted && !property.TryConvert(ref value))
550 Console.WriteLine("SetValue", "Can not convert {0} to type '{1}'", value, property.ReturnType);
554 if (property.ValidateValue != null && !property.ValidateValue(this, value))
555 throw new ArgumentException("Value was an invalid value for " + property.PropertyName, "value");
557 if (property.CoerceValue != null)
558 value = property.CoerceValue(this, value);
560 BindablePropertyContext context = GetOrCreateContext(property);
562 context.Attributes |= BindableContextAttributes.IsManuallySet;
563 context.Attributes &= ~BindableContextAttributes.IsSetFromStyle;
565 context.Attributes &= ~BindableContextAttributes.IsManuallySet;
568 context.Attributes |= BindableContextAttributes.IsSetFromStyle;
569 // else omitted on purpose
571 bool currentlyApplying = _applying;
573 if ((context.Attributes & BindableContextAttributes.IsBeingSet) != 0)
575 Queue<SetValueArgs> delayQueue = context.DelayedSetters;
576 if (delayQueue == null)
577 context.DelayedSetters = delayQueue = new Queue<SetValueArgs>();
579 delayQueue.Enqueue(new SetValueArgs(property, context, value, currentlyApplying, attributes));
583 context.Attributes |= BindableContextAttributes.IsBeingSet;
584 SetValueActual(property, context, value, currentlyApplying, forceSendChangeSignal, attributes, silent);
586 Queue<SetValueArgs> delayQueue = context.DelayedSetters;
587 if (delayQueue != null)
589 while (delayQueue.Count > 0)
591 SetValueArgs s = delayQueue.Dequeue();
592 SetValueActual(s.Property, s.Context, s.Value, s.CurrentlyApplying, forceSendChangeSignal, s.Attributes);
595 context.DelayedSetters = null;
598 context.Attributes &= ~BindableContextAttributes.IsBeingSet;
602 internal void ApplyBindings(bool skipBindingContext, bool fromBindingContextChanged)
604 var prop = _properties.ToArray();
605 for (int i = 0, propLength = prop.Length; i < propLength; i++) {
606 BindablePropertyContext context = prop [i];
607 BindingBase binding = context.Binding;
611 if (skipBindingContext && ReferenceEquals(context.Property, BindingContextProperty))
614 binding.Unapply(fromBindingContextChanged: fromBindingContextChanged);
615 binding.Apply(BindingContext, this, context.Property, fromBindingContextChanged: fromBindingContextChanged);
619 static void BindingContextPropertyBindingChanging(BindableObject bindable, BindingBase oldBindingBase, BindingBase newBindingBase)
621 object context = bindable._inheritedContext;
622 var oldBinding = oldBindingBase as Binding;
623 var newBinding = newBindingBase as Binding;
625 if (context == null && oldBinding != null)
626 context = oldBinding.Context;
627 if (context != null && newBinding != null)
628 newBinding.Context = context;
631 static void BindingContextPropertyChanged(BindableObject bindable, object oldvalue, object newvalue)
633 bindable._inheritedContext = null;
634 bindable.ApplyBindings(skipBindingContext: true, fromBindingContextChanged:true);
635 bindable.OnBindingContextChanged();
638 void ClearValue(BindableProperty property, bool fromStyle, bool checkAccess)
640 if (property == null)
641 throw new ArgumentNullException(nameof(property));
643 if (checkAccess && property.IsReadOnly)
644 throw new InvalidOperationException(string.Format("The BindableProperty \"{0}\" is readonly.", property.PropertyName));
646 BindablePropertyContext bpcontext = GetContext(property);
647 if (bpcontext == null)
650 if (fromStyle && !CanBeSetFromStyle(property))
653 object original = bpcontext.Value;
655 object newValue = property.GetDefaultValue(this);
657 bool same = Equals(original, newValue);
660 property.PropertyChanging?.Invoke(this, original, newValue);
662 OnPropertyChanging(property.PropertyName);
665 bpcontext.Attributes &= ~BindableContextAttributes.IsManuallySet;
666 bpcontext.Value = newValue;
667 if (property.DefaultValueCreator == null)
668 bpcontext.Attributes |= BindableContextAttributes.IsDefaultValue;
670 bpcontext.Attributes |= BindableContextAttributes.IsDefaultValueCreated;
674 OnPropertyChanged(property.PropertyName);
675 property.PropertyChanged?.Invoke(this, original, newValue);
679 [MethodImpl(MethodImplOptions.AggressiveInlining)]
680 BindablePropertyContext CreateAndAddContext(BindableProperty property)
682 var context = new BindablePropertyContext { Property = property, Value = property.DefaultValueCreator != null ? property.DefaultValueCreator(this) : property.DefaultValue };
684 if (property.DefaultValueCreator == null)
685 context.Attributes = BindableContextAttributes.IsDefaultValue;
687 context.Attributes = BindableContextAttributes.IsDefaultValueCreated;
689 _properties.Add(context);
693 [MethodImpl(MethodImplOptions.AggressiveInlining)]
694 BindablePropertyContext GetContext(BindableProperty property)
696 List<BindablePropertyContext> properties = _properties;
698 for (var i = 0; i < properties.Count; i++)
700 BindablePropertyContext context = properties[i];
701 if (ReferenceEquals(context.Property, property))
708 [MethodImpl(MethodImplOptions.AggressiveInlining)]
709 BindablePropertyContext GetOrCreateContext(BindableProperty property)
711 BindablePropertyContext context = GetContext(property);
714 context = CreateAndAddContext(property);
716 else if (property.DefaultValueCreator != null )
718 context.Value = property.DefaultValueCreator(this); //Update Value from dali
724 void RemoveBinding(BindableProperty property, BindablePropertyContext context)
726 context.Binding.Unapply();
728 property.BindingChanging?.Invoke(this, context.Binding, null);
730 context.Binding = null;
733 void SetValue(BindableProperty property, object value, bool fromStyle, bool checkAccess)
735 if (property == null)
736 throw new ArgumentNullException("property");
738 if (checkAccess && property.IsReadOnly)
739 throw new InvalidOperationException(string.Format("The BindableProperty \"{0}\" is readonly.", property.PropertyName));
741 if (fromStyle && !CanBeSetFromStyle(property))
744 SetValueCore(property, value, SetValueFlags.ClearOneWayBindings | SetValueFlags.ClearDynamicResource,
745 (fromStyle ? SetValuePrivateFlags.FromStyle : SetValuePrivateFlags.ManuallySet) | (checkAccess ? SetValuePrivateFlags.CheckAccess : 0),
749 void SetValueActual(BindableProperty property, BindablePropertyContext context, object value, bool currentlyApplying, bool forceSendChangeSignal, SetValueFlags attributes, bool silent = false)
751 object original = context.Value;
752 bool raiseOnEqual = (attributes & SetValueFlags.RaiseOnEqual) != 0;
753 bool clearDynamicResources = (attributes & SetValueFlags.ClearDynamicResource) != 0;
754 bool clearOneWayBindings = (attributes & SetValueFlags.ClearOneWayBindings) != 0;
755 bool clearTwoWayBindings = (attributes & SetValueFlags.ClearTwoWayBindings) != 0;
757 bool same = ReferenceEquals(context.Property, BindingContextProperty) ? ReferenceEquals(value, original) : Equals(value, original);
758 if (!silent && (!same || raiseOnEqual))
760 property.PropertyChanging?.Invoke(this, original, value);
762 OnPropertyChanging(property.PropertyName);
765 if (!same || raiseOnEqual)
767 context.Value = value;
770 context.Attributes &= ~BindableContextAttributes.IsDefaultValue;
771 context.Attributes &= ~BindableContextAttributes.IsDefaultValueCreated;
773 if ((context.Attributes & BindableContextAttributes.IsDynamicResource) != 0 && clearDynamicResources)
774 RemoveDynamicResource(property);
776 BindingBase binding = context.Binding;
779 if (clearOneWayBindings && binding.GetRealizedMode(property) == BindingMode.OneWay || clearTwoWayBindings && binding.GetRealizedMode(property) == BindingMode.TwoWay)
781 RemoveBinding(property, context);
788 if ((!same || raiseOnEqual))
790 property.PropertyChanged?.Invoke(this, original, value);
792 if (binding != null && !currentlyApplying)
799 OnPropertyChanged(property.PropertyName);
801 else if (true == same && true == forceSendChangeSignal)
803 if (binding != null && !currentlyApplying)
810 OnPropertyChanged(property.PropertyName);
816 enum BindableContextAttributes
818 IsManuallySet = 1 << 0,
820 IsDynamicResource = 1 << 2,
821 IsSetFromStyle = 1 << 3,
822 IsDefaultValue = 1 << 4,
823 IsDefaultValueCreated = 1 << 5,
826 class BindablePropertyContext
828 public BindableContextAttributes Attributes;
829 public BindingBase Binding;
830 public Queue<SetValueArgs> DelayedSetters;
831 public BindableProperty Property;
836 internal enum SetValuePrivateFlags
839 CheckAccess = 1 << 0,
841 ManuallySet = 1 << 2,
844 Default = CheckAccess
849 public readonly SetValueFlags Attributes;
850 public readonly BindablePropertyContext Context;
851 public readonly bool CurrentlyApplying;
852 public readonly BindableProperty Property;
853 public readonly object Value;
855 public SetValueArgs(BindableProperty property, BindablePropertyContext context, object value, bool currentlyApplying, SetValueFlags attributes)
860 CurrentlyApplying = currentlyApplying;
861 Attributes = attributes;
867 namespace Tizen.NUI.Binding.Internals
870 /// SetValueFlags. For internal use.
873 [EditorBrowsable(EditorBrowsableState.Never)]
874 public enum SetValueFlags
879 /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
880 [EditorBrowsable(EditorBrowsableState.Never)]
884 /// Clear OneWay bindings.
886 /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
887 [EditorBrowsable(EditorBrowsableState.Never)]
888 ClearOneWayBindings = 1 << 0,
891 /// Clear TwoWay bindings.
893 /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
894 [EditorBrowsable(EditorBrowsableState.Never)]
895 ClearTwoWayBindings = 1 << 1,
898 /// Clear dynamic resource.
900 /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
901 [EditorBrowsable(EditorBrowsableState.Never)]
902 ClearDynamicResource = 1 << 2,
907 /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
908 [EditorBrowsable(EditorBrowsableState.Never)]
909 RaiseOnEqual = 1 << 3