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 internal abstract class BindableObject : INotifyPropertyChanged, IDynamicResourceHandler
18 /// Implements the bound property whose interface is provided by the BindingContext property.
20 public static readonly BindableProperty BindingContextProperty =
21 BindableProperty.Create("BindingContext", typeof(object), typeof(BindableObject), default(object),
22 BindingMode.OneWay, null, BindingContextPropertyChanged, null, null, BindingContextPropertyBindingChanging);
24 readonly List<BindablePropertyContext> _properties = new List<BindablePropertyContext>(4);
27 object _inheritedContext;
30 /// Gets or sets object that contains the properties that will be targeted by the bound properties that belong to this BindableObject.
32 /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
33 [EditorBrowsable(EditorBrowsableState.Never)]
34 public object BindingContext
36 get { return _inheritedContext ?? GetValue(BindingContextProperty); }
37 set { SetValue(BindingContextProperty, value); }
40 void IDynamicResourceHandler.SetDynamicResource(BindableProperty property, string key)
42 SetDynamicResource(property, key, false);
46 /// Raised when a property has changed.
48 /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
49 [EditorBrowsable(EditorBrowsableState.Never)]
50 public event PropertyChangedEventHandler PropertyChanged;
53 /// Raised whenever the BindingContext property changes.
55 /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
56 [EditorBrowsable(EditorBrowsableState.Never)]
57 public event EventHandler BindingContextChanged;
59 internal void ClearValue(BindableProperty property, bool fromStyle)
61 ClearValue(property, fromStyle: fromStyle, checkAccess: true);
65 /// Clears any value set by Tizen.NUI.Xaml.BindableObject.SetValue.
67 /// <param name="property">The BindableProperty to clear</param>
68 internal void ClearValue(BindableProperty property)
70 ClearValue(property, fromStyle: false, checkAccess: true);
74 /// Clears any value set by Tizen.NUI.Xaml.BindableObject.SetValue for the property that is identified by propertyKey.
76 /// <param name="propertyKey">The BindablePropertyKey that identifies the BindableProperty to clear.</param>
77 internal void ClearValue(BindablePropertyKey propertyKey)
79 if (propertyKey == null)
80 throw new ArgumentNullException("propertyKey");
82 ClearValue(propertyKey.BindableProperty, fromStyle:false, checkAccess: false);
86 /// Return true if the target property exists and has been set.
88 /// <param name="targetProperty">The target property</param>
89 /// <returns>return true if the target property exists and has been set</returns>
90 internal bool IsSet(BindableProperty targetProperty)
92 if (targetProperty == null)
93 throw new ArgumentNullException(nameof(targetProperty));
95 var bpcontext = GetContext(targetProperty);
96 return bpcontext != null
97 && (bpcontext.Attributes & BindableContextAttributes.IsDefaultValue) == 0;
101 /// Returns the value that is contained the BindableProperty.
103 /// <param name="property">The BindableProperty for which to get the value.</param>
104 /// <returns>The value that is contained the BindableProperty</returns>
105 /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
106 [EditorBrowsable(EditorBrowsableState.Never)]
107 public object GetValue(BindableProperty property)
109 if (property == null)
110 throw new ArgumentNullException("property");
112 BindablePropertyContext context = property.DefaultValueCreator != null ? GetOrCreateContext(property) : GetContext(property);
115 return property.DefaultValue;
117 return context.Value;
121 /// Raised when a property is about to change.
123 /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
124 [EditorBrowsable(EditorBrowsableState.Never)]
125 public event PropertyChangingEventHandler PropertyChanging;
128 /// Removes a previously set binding.
130 /// <param name="property">The BindableProperty from which to remove bindings.</param>
131 internal void RemoveBinding(BindableProperty property)
133 if (property == null)
134 throw new ArgumentNullException("property");
136 BindablePropertyContext context = GetContext(property);
137 if (context == null || context.Binding == null)
140 RemoveBinding(property, context);
144 /// Assigns a binding to a property.
146 /// <param name="targetProperty">The BindableProperty on which to set a binding.</param>
147 /// <param name="binding">The binding to set.</param>
148 public void SetBinding(BindableProperty targetProperty, BindingBase binding)
150 SetBinding(targetProperty, binding, false);
153 private bool isCreateByXaml = false;
154 internal virtual bool IsCreateByXaml
158 return isCreateByXaml;
162 isCreateByXaml = value;
167 /// Sets the value of the specified property.
169 /// <param name="property">The BindableProperty on which to assign a value.</param>
170 /// <param name="value">The value to set.</param>
171 /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
172 [EditorBrowsable(EditorBrowsableState.Never)]
173 public void SetValue(BindableProperty property, object value)
175 SetValue(property, value, false, true);
176 //if (true == isCreateByXaml)
178 // SetValue(property, value, false, true);
182 // property.PropertyChanged?.Invoke(this, null, value);
186 internal void SetValueAndForceSendChangeSignal(BindableProperty property, object value)
188 if (property == null)
189 throw new ArgumentNullException("property");
191 if (property.IsReadOnly)
192 throw new InvalidOperationException(string.Format("The BindableProperty \"{0}\" is readonly.", property.PropertyName));
194 SetValueCore(property, value, SetValueFlags.ClearOneWayBindings | SetValueFlags.ClearDynamicResource,
195 SetValuePrivateFlags.ManuallySet | SetValuePrivateFlags.CheckAccess, true);
197 //if (true == isCreateByXaml)
199 // if (property.IsReadOnly)
200 // throw new InvalidOperationException(string.Format("The BindableProperty \"{0}\" is readonly.", property.PropertyName));
202 // SetValueCore(property, value, SetValueFlags.ClearOneWayBindings | SetValueFlags.ClearDynamicResource,
203 // SetValuePrivateFlags.ManuallySet | SetValuePrivateFlags.CheckAccess, true);
207 // property.PropertyChanged?.Invoke(this, null, value);
212 /// Sets the value of the propertyKey.
214 /// <param name="propertyKey">The BindablePropertyKey on which to assign a value.</param>
215 /// <param name="value">The value to set.</param>
216 /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
217 [EditorBrowsable(EditorBrowsableState.Never)]
218 public void SetValue(BindablePropertyKey propertyKey, object value)
220 if (propertyKey == null)
221 throw new ArgumentNullException("propertyKey");
223 SetValue(propertyKey.BindableProperty, value, false, false);
227 /// Set the inherited context to a neated element.
229 /// <param name="bindable">The object on which to set the inherited binding context.</param>
230 /// <param name="value">The inherited context to set.</param>
231 [EditorBrowsable(EditorBrowsableState.Never)]
232 public static void SetInheritedBindingContext(BindableObject bindable, object value)
234 BindablePropertyContext bpContext = bindable.GetContext(BindingContextProperty);
235 if (bpContext != null && ((bpContext.Attributes & BindableContextAttributes.IsManuallySet) != 0))
238 object oldContext = bindable._inheritedContext;
240 if (ReferenceEquals(oldContext, value))
243 if (bpContext != null && oldContext == null)
244 oldContext = bpContext.Value;
246 if (bpContext != null && bpContext.Binding != null)
248 bpContext.Binding.Context = value;
249 bindable._inheritedContext = null;
253 bindable._inheritedContext = value;
256 bindable.ApplyBindings(skipBindingContext:false, fromBindingContextChanged:true);
257 bindable.OnBindingContextChanged();
261 /// Apply the bindings to BindingContext.
263 /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
264 [EditorBrowsable(EditorBrowsableState.Never)]
265 protected void ApplyBindings()
267 ApplyBindings(skipBindingContext: false, fromBindingContextChanged: false);
271 /// Override this method to execute an action when the BindingContext changes.
273 /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
274 [EditorBrowsable(EditorBrowsableState.Never)]
275 protected virtual void OnBindingContextChanged()
277 BindingContextChanged?.Invoke(this, EventArgs.Empty);
281 /// Call this method from a child class to notify that a change happened on a property.
283 /// <param name="propertyName">The name of the property that changed.</param>
284 /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
285 [EditorBrowsable(EditorBrowsableState.Never)]
286 protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
287 => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
290 /// Call this method from a child class to notify that a change is going to happen on a property.
292 /// <param name="propertyName">The name of the property that is changing.</param>
293 /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
294 [EditorBrowsable(EditorBrowsableState.Never)]
295 protected virtual void OnPropertyChanging([CallerMemberName] string propertyName = null)
296 => PropertyChanging?.Invoke(this, new PropertyChangingEventArgs(propertyName));
299 /// Unapplies all previously set bindings.
301 /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
302 [EditorBrowsable(EditorBrowsableState.Never)]
303 protected void UnapplyBindings()
305 for (int i = 0, _propertiesCount = _properties.Count; i < _propertiesCount; i++) {
306 BindablePropertyContext context = _properties [i];
307 if (context.Binding == null)
310 context.Binding.Unapply();
314 internal bool GetIsBound(BindableProperty targetProperty)
316 if (targetProperty == null)
317 throw new ArgumentNullException("targetProperty");
319 BindablePropertyContext bpcontext = GetContext(targetProperty);
320 return bpcontext != null && bpcontext.Binding != null;
324 /// Returns the value that is contained the BindableProperty.
326 /// <param name="property0">The BindableProperty instance.</param>
327 /// <param name="property1">The BindableProperty instance.</param>
328 /// <returns>The value that is contained the BindableProperty</returns>
329 internal object[] GetValues(BindableProperty property0, BindableProperty property1)
331 var values = new object[2];
333 for (var i = 0; i < _properties.Count; i++)
335 BindablePropertyContext context = _properties[i];
337 if (ReferenceEquals(context.Property, property0))
339 values[0] = context.Value;
342 else if (ReferenceEquals(context.Property, property1))
344 values[1] = context.Value;
348 if (property0 == null && property1 == null)
352 if (!ReferenceEquals(property0, null))
353 values[0] = property0.DefaultValueCreator == null ? property0.DefaultValue : CreateAndAddContext(property0).Value;
354 if (!ReferenceEquals(property1, null))
355 values[1] = property1.DefaultValueCreator == null ? property1.DefaultValue : CreateAndAddContext(property1).Value;
361 /// Returns the value that is contained the BindableProperty.
363 /// <param name="property0">The BindableProperty instance.</param>
364 /// <param name="property1">The BindableProperty instance.</param>
365 /// <param name="property2">The BindableProperty instance.</param>
366 /// <returns>The value that is contained the BindableProperty</returns>
367 internal object[] GetValues(BindableProperty property0, BindableProperty property1, BindableProperty property2)
369 var values = new object[3];
371 for (var i = 0; i < _properties.Count; i++)
373 BindablePropertyContext context = _properties[i];
375 if (ReferenceEquals(context.Property, property0))
377 values[0] = context.Value;
380 else if (ReferenceEquals(context.Property, property1))
382 values[1] = context.Value;
385 else if (ReferenceEquals(context.Property, property2))
387 values[2] = context.Value;
391 if (property0 == null && property1 == null && property2 == null)
395 if (!ReferenceEquals(property0, null))
396 values[0] = property0.DefaultValueCreator == null ? property0.DefaultValue : CreateAndAddContext(property0).Value;
397 if (!ReferenceEquals(property1, null))
398 values[1] = property1.DefaultValueCreator == null ? property1.DefaultValue : CreateAndAddContext(property1).Value;
399 if (!ReferenceEquals(property2, null))
400 values[2] = property2.DefaultValueCreator == null ? property2.DefaultValue : CreateAndAddContext(property2).Value;
406 /// Returns the value that is contained the BindableProperty.
408 /// <param name="properties">The array of the BindableProperty instances</param>
409 /// <returns>The values that is contained the BindableProperty instances.</returns>
410 internal object[] GetValues(params BindableProperty[] properties)
412 var values = new object[properties.Length];
413 for (var i = 0; i < _properties.Count; i++) {
414 var context = _properties[i];
415 var index = properties.IndexOf(context.Property);
418 values[index] = context.Value;
420 for (var i = 0; i < values.Length; i++) {
421 if (!ReferenceEquals(values[i], null))
423 values[i] = properties[i].DefaultValueCreator == null ? properties[i].DefaultValue : CreateAndAddContext(properties[i]).Value;
428 internal virtual void OnRemoveDynamicResource(BindableProperty property)
432 internal virtual void OnSetDynamicResource(BindableProperty property, string key)
436 internal void RemoveDynamicResource(BindableProperty property)
438 if (property == null)
439 throw new ArgumentNullException("property");
441 OnRemoveDynamicResource(property);
442 BindablePropertyContext context = GetOrCreateContext(property);
443 context.Attributes &= ~BindableContextAttributes.IsDynamicResource;
446 internal void SetBinding(BindableProperty targetProperty, BindingBase binding, bool fromStyle)
448 if (targetProperty == null)
449 throw new ArgumentNullException("targetProperty");
451 throw new ArgumentNullException("binding");
453 if (fromStyle && !CanBeSetFromStyle(targetProperty))
456 var context = GetOrCreateContext(targetProperty);
458 context.Attributes |= BindableContextAttributes.IsSetFromStyle;
460 context.Attributes &= ~BindableContextAttributes.IsSetFromStyle;
462 if (context.Binding != null)
463 context.Binding.Unapply();
465 BindingBase oldBinding = context.Binding;
466 context.Binding = binding;
468 targetProperty.BindingChanging?.Invoke(this, oldBinding, binding);
470 binding.Apply(BindingContext, this, targetProperty);
473 bool CanBeSetFromStyle(BindableProperty property)
475 var context = GetContext(property);
478 if ((context.Attributes & BindableContextAttributes.IsSetFromStyle) == BindableContextAttributes.IsSetFromStyle)
480 if ((context.Attributes & BindableContextAttributes.IsDefaultValue) == BindableContextAttributes.IsDefaultValue)
482 if ((context.Attributes & BindableContextAttributes.IsDefaultValueCreated) == BindableContextAttributes.IsDefaultValueCreated)
487 internal void SetDynamicResource(BindableProperty property, string key)
489 SetDynamicResource(property, key, false);
492 internal void SetDynamicResource(BindableProperty property, string key, bool fromStyle)
494 if (property == null)
495 throw new ArgumentNullException(nameof(property));
496 if (string.IsNullOrEmpty(key))
497 throw new ArgumentNullException(nameof(key));
498 if (fromStyle && !CanBeSetFromStyle(property))
501 var context = GetOrCreateContext(property);
503 context.Attributes |= BindableContextAttributes.IsDynamicResource;
505 context.Attributes |= BindableContextAttributes.IsSetFromStyle;
507 context.Attributes &= ~BindableContextAttributes.IsSetFromStyle;
509 OnSetDynamicResource(property, key);
512 internal void SetValue(BindableProperty property, object value, bool fromStyle)
514 SetValue(property, value, fromStyle, true);
517 internal void SetValueCore(BindablePropertyKey propertyKey, object value, SetValueFlags attributes = SetValueFlags.None)
519 SetValueCore(propertyKey.BindableProperty, value, attributes, SetValuePrivateFlags.None, false);
523 /// For internal use.
525 /// <param name="property">The BindableProperty on which to assign a value.</param>
526 /// <param name="value">The value to set</param>
527 /// <param name="attributes">The set value flag</param>
528 [EditorBrowsable(EditorBrowsableState.Never)]
529 internal void SetValueCore(BindableProperty property, object value, SetValueFlags attributes = SetValueFlags.None)
531 SetValueCore(property, value, attributes, SetValuePrivateFlags.Default, false);
534 internal void SetValueCore(BindableProperty property, object value, SetValueFlags attributes, SetValuePrivateFlags privateAttributes, bool forceSendChangeSignal)
536 bool checkAccess = (privateAttributes & SetValuePrivateFlags.CheckAccess) != 0;
537 bool manuallySet = (privateAttributes & SetValuePrivateFlags.ManuallySet) != 0;
538 bool silent = (privateAttributes & SetValuePrivateFlags.Silent) != 0;
539 bool fromStyle = (privateAttributes & SetValuePrivateFlags.FromStyle) != 0;
540 bool converted = (privateAttributes & SetValuePrivateFlags.Converted) != 0;
542 if (property == null)
543 throw new ArgumentNullException("property");
544 if (checkAccess && property.IsReadOnly)
546 Debug.WriteLine("Can not set the BindableProperty \"{0}\" because it is readonly.", property.PropertyName);
550 if (!converted && !property.TryConvert(ref value))
552 Console.WriteLine("SetValue", "Can not convert {0} to type '{1}'", value, property.ReturnType);
556 if (property.ValidateValue != null && !property.ValidateValue(this, value))
557 throw new ArgumentException("Value was an invalid value for " + property.PropertyName, "value");
559 if (property.CoerceValue != null)
560 value = property.CoerceValue(this, value);
562 BindablePropertyContext context = GetOrCreateContext(property);
564 context.Attributes |= BindableContextAttributes.IsManuallySet;
565 context.Attributes &= ~BindableContextAttributes.IsSetFromStyle;
567 context.Attributes &= ~BindableContextAttributes.IsManuallySet;
570 context.Attributes |= BindableContextAttributes.IsSetFromStyle;
571 // else omitted on purpose
573 bool currentlyApplying = _applying;
575 if ((context.Attributes & BindableContextAttributes.IsBeingSet) != 0)
577 Queue<SetValueArgs> delayQueue = context.DelayedSetters;
578 if (delayQueue == null)
579 context.DelayedSetters = delayQueue = new Queue<SetValueArgs>();
581 delayQueue.Enqueue(new SetValueArgs(property, context, value, currentlyApplying, attributes));
585 context.Attributes |= BindableContextAttributes.IsBeingSet;
586 SetValueActual(property, context, value, currentlyApplying, forceSendChangeSignal, attributes, silent);
588 Queue<SetValueArgs> delayQueue = context.DelayedSetters;
589 if (delayQueue != null)
591 while (delayQueue.Count > 0)
593 SetValueArgs s = delayQueue.Dequeue();
594 SetValueActual(s.Property, s.Context, s.Value, s.CurrentlyApplying, forceSendChangeSignal, s.Attributes);
597 context.DelayedSetters = null;
600 context.Attributes &= ~BindableContextAttributes.IsBeingSet;
604 internal void ApplyBindings(bool skipBindingContext, bool fromBindingContextChanged)
606 var prop = _properties.ToArray();
607 for (int i = 0, propLength = prop.Length; i < propLength; i++) {
608 BindablePropertyContext context = prop [i];
609 BindingBase binding = context.Binding;
613 if (skipBindingContext && ReferenceEquals(context.Property, BindingContextProperty))
616 binding.Unapply(fromBindingContextChanged: fromBindingContextChanged);
617 binding.Apply(BindingContext, this, context.Property, fromBindingContextChanged: fromBindingContextChanged);
621 static void BindingContextPropertyBindingChanging(BindableObject bindable, BindingBase oldBindingBase, BindingBase newBindingBase)
623 object context = bindable._inheritedContext;
624 var oldBinding = oldBindingBase as Binding;
625 var newBinding = newBindingBase as Binding;
627 if (context == null && oldBinding != null)
628 context = oldBinding.Context;
629 if (context != null && newBinding != null)
630 newBinding.Context = context;
633 static void BindingContextPropertyChanged(BindableObject bindable, object oldvalue, object newvalue)
635 bindable._inheritedContext = null;
636 bindable.ApplyBindings(skipBindingContext: true, fromBindingContextChanged:true);
637 bindable.OnBindingContextChanged();
640 void ClearValue(BindableProperty property, bool fromStyle, bool checkAccess)
642 if (property == null)
643 throw new ArgumentNullException(nameof(property));
645 if (checkAccess && property.IsReadOnly)
646 throw new InvalidOperationException(string.Format("The BindableProperty \"{0}\" is readonly.", property.PropertyName));
648 BindablePropertyContext bpcontext = GetContext(property);
649 if (bpcontext == null)
652 if (fromStyle && !CanBeSetFromStyle(property))
655 object original = bpcontext.Value;
657 object newValue = property.GetDefaultValue(this);
659 bool same = Equals(original, newValue);
662 property.PropertyChanging?.Invoke(this, original, newValue);
664 OnPropertyChanging(property.PropertyName);
667 bpcontext.Attributes &= ~BindableContextAttributes.IsManuallySet;
668 bpcontext.Value = newValue;
669 if (property.DefaultValueCreator == null)
670 bpcontext.Attributes |= BindableContextAttributes.IsDefaultValue;
672 bpcontext.Attributes |= BindableContextAttributes.IsDefaultValueCreated;
676 OnPropertyChanged(property.PropertyName);
677 property.PropertyChanged?.Invoke(this, original, newValue);
681 [MethodImpl(MethodImplOptions.AggressiveInlining)]
682 BindablePropertyContext CreateAndAddContext(BindableProperty property)
684 var context = new BindablePropertyContext { Property = property, Value = property.DefaultValueCreator != null ? property.DefaultValueCreator(this) : property.DefaultValue };
686 if (property.DefaultValueCreator == null)
687 context.Attributes = BindableContextAttributes.IsDefaultValue;
689 context.Attributes = BindableContextAttributes.IsDefaultValueCreated;
691 _properties.Add(context);
695 [MethodImpl(MethodImplOptions.AggressiveInlining)]
696 BindablePropertyContext GetContext(BindableProperty property)
698 List<BindablePropertyContext> properties = _properties;
700 for (var i = 0; i < properties.Count; i++)
702 BindablePropertyContext context = properties[i];
703 if (ReferenceEquals(context.Property, property))
710 [MethodImpl(MethodImplOptions.AggressiveInlining)]
711 BindablePropertyContext GetOrCreateContext(BindableProperty property)
713 BindablePropertyContext context = GetContext(property);
716 context = CreateAndAddContext(property);
718 else if (property.DefaultValueCreator != null )
720 context.Value = property.DefaultValueCreator(this); //Update Value from dali
726 void RemoveBinding(BindableProperty property, BindablePropertyContext context)
728 context.Binding.Unapply();
730 property.BindingChanging?.Invoke(this, context.Binding, null);
732 context.Binding = null;
735 void SetValue(BindableProperty property, object value, bool fromStyle, bool checkAccess)
737 if (property == null)
738 throw new ArgumentNullException("property");
740 if (checkAccess && property.IsReadOnly)
741 throw new InvalidOperationException(string.Format("The BindableProperty \"{0}\" is readonly.", property.PropertyName));
743 if (fromStyle && !CanBeSetFromStyle(property))
746 SetValueCore(property, value, SetValueFlags.ClearOneWayBindings | SetValueFlags.ClearDynamicResource,
747 (fromStyle ? SetValuePrivateFlags.FromStyle : SetValuePrivateFlags.ManuallySet) | (checkAccess ? SetValuePrivateFlags.CheckAccess : 0),
751 void SetValueActual(BindableProperty property, BindablePropertyContext context, object value, bool currentlyApplying, bool forceSendChangeSignal, SetValueFlags attributes, bool silent = false)
753 object original = context.Value;
754 bool raiseOnEqual = (attributes & SetValueFlags.RaiseOnEqual) != 0;
755 bool clearDynamicResources = (attributes & SetValueFlags.ClearDynamicResource) != 0;
756 bool clearOneWayBindings = (attributes & SetValueFlags.ClearOneWayBindings) != 0;
757 bool clearTwoWayBindings = (attributes & SetValueFlags.ClearTwoWayBindings) != 0;
759 bool same = ReferenceEquals(context.Property, BindingContextProperty) ? ReferenceEquals(value, original) : Equals(value, original);
760 if (!silent && (!same || raiseOnEqual))
762 property.PropertyChanging?.Invoke(this, original, value);
764 OnPropertyChanging(property.PropertyName);
767 if (!same || raiseOnEqual)
769 context.Value = value;
772 context.Attributes &= ~BindableContextAttributes.IsDefaultValue;
773 context.Attributes &= ~BindableContextAttributes.IsDefaultValueCreated;
775 if ((context.Attributes & BindableContextAttributes.IsDynamicResource) != 0 && clearDynamicResources)
776 RemoveDynamicResource(property);
778 BindingBase binding = context.Binding;
781 if (clearOneWayBindings && binding.GetRealizedMode(property) == BindingMode.OneWay || clearTwoWayBindings && binding.GetRealizedMode(property) == BindingMode.TwoWay)
783 RemoveBinding(property, context);
790 if ((!same || raiseOnEqual))
792 property.PropertyChanged?.Invoke(this, original, value);
794 if (binding != null && !currentlyApplying)
801 OnPropertyChanged(property.PropertyName);
803 else if (true == same && true == forceSendChangeSignal)
805 if (binding != null && !currentlyApplying)
812 OnPropertyChanged(property.PropertyName);
818 enum BindableContextAttributes
820 IsManuallySet = 1 << 0,
822 IsDynamicResource = 1 << 2,
823 IsSetFromStyle = 1 << 3,
824 IsDefaultValue = 1 << 4,
825 IsDefaultValueCreated = 1 << 5,
828 class BindablePropertyContext
830 public BindableContextAttributes Attributes;
831 public BindingBase Binding;
832 public Queue<SetValueArgs> DelayedSetters;
833 public BindableProperty Property;
838 internal enum SetValuePrivateFlags
841 CheckAccess = 1 << 0,
843 ManuallySet = 1 << 2,
846 Default = CheckAccess
851 public readonly SetValueFlags Attributes;
852 public readonly BindablePropertyContext Context;
853 public readonly bool CurrentlyApplying;
854 public readonly BindableProperty Property;
855 public readonly object Value;
857 public SetValueArgs(BindableProperty property, BindablePropertyContext context, object value, bool currentlyApplying, SetValueFlags attributes)
862 CurrentlyApplying = currentlyApplying;
863 Attributes = attributes;
869 namespace Tizen.NUI.Binding.Internals
872 /// SetValueFlags. For internal use.
875 [EditorBrowsable(EditorBrowsableState.Never)]
876 public enum SetValueFlags
881 /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
882 [EditorBrowsable(EditorBrowsableState.Never)]
886 /// Clear OneWay bindings.
888 /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
889 [EditorBrowsable(EditorBrowsableState.Never)]
890 ClearOneWayBindings = 1 << 0,
893 /// Clear TwoWay bindings.
895 /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
896 [EditorBrowsable(EditorBrowsableState.Never)]
897 ClearTwoWayBindings = 1 << 1,
900 /// Clear dynamic resource.
902 /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
903 [EditorBrowsable(EditorBrowsableState.Never)]
904 ClearDynamicResource = 1 << 2,
909 /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
910 [EditorBrowsable(EditorBrowsableState.Never)]
911 RaiseOnEqual = 1 << 3