[NUI] Public RemoveBinding and ClearBinding apis
[platform/core/csapi/tizenfx.git] / src / Tizen.NUI / src / public / XamlBinding / BindableObject.cs
index bba0b23..b5390fa 100755 (executable)
-using System;
+/*
+ * Copyright(c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+using System;
 using System.Collections.Generic;
 using System.ComponentModel;
 using System.Diagnostics;
 using System.Reflection;
+using System.Linq;
 using System.Runtime.CompilerServices;
-using Tizen.NUI.Internals;
+using Tizen.NUI.Binding.Internals;
 
 namespace Tizen.NUI.Binding
 {
     /// <summary>
-    /// 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.
+    /// Provides a mechanism by which application developers can propagate changes that are made to data in one object to another.
     /// </summary>
-       public abstract class BindableObject : INotifyPropertyChanged, IDynamicResourceHandler
-       {
+    /// <since_tizen> 9 </since_tizen>
+    public abstract class BindableObject : INotifyPropertyChanged, IDynamicResourceHandler
+    {
         /// <summary>
         /// Implements the bound property whose interface is provided by the BindingContext property.
         /// </summary>
-               public static readonly BindableProperty BindingContextProperty =
-                       BindableProperty.Create("BindingContext", typeof(object), typeof(BindableObject), default(object),
-                                                                       BindingMode.OneWay, null, BindingContextPropertyChanged, null, null, BindingContextPropertyBindingChanging);
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static readonly BindableProperty BindingContextProperty =
+            BindableProperty.Create(nameof(BindingContext), typeof(object), typeof(BindableObject),  default(object), BindingMode.OneWay, null, BindingContextPropertyChanged,
+            null, null, BindingContextPropertyBindingChanging);
 
-               readonly List<BindablePropertyContext> _properties = new List<BindablePropertyContext>(4);
+        readonly Dictionary<BindableProperty, BindablePropertyContext> properties = new Dictionary<BindableProperty, BindablePropertyContext>(4);
 
-               bool _applying;
-               object _inheritedContext;
+        bool applying;
+        object inheritedContext;
 
         /// <summary>
         /// Gets or sets object that contains the properties that will be targeted by the bound properties that belong to this BindableObject.
         /// </summary>
-               public object BindingContext
-               {
-                       get { return _inheritedContext ?? GetValue(BindingContextProperty); }
-                       set { SetValue(BindingContextProperty, value); }
-               }
+        /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public object BindingContext
+        {
+            get { return inheritedContext ?? GetValue(BindingContextProperty); }
+            set { SetValue(BindingContextProperty, value); }
+        }
 
-               void IDynamicResourceHandler.SetDynamicResource(BindableProperty property, string key)
-               {
-                       SetDynamicResource(property, key, false);
-               }
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public int LineNumber { get; set; } = -1;
+
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public int LinePosition { get; set; } = -1;
+
+        void IDynamicResourceHandler.SetDynamicResource(BindableProperty property, string key) => SetDynamicResource(property, key, false);
 
         /// <summary>
         /// Raised when a property has changed.
         /// </summary>
-               public event PropertyChangedEventHandler PropertyChanged;
+        /// <since_tizen> 9 </since_tizen>
+        public event PropertyChangedEventHandler PropertyChanged;
+
+        /// <summary>Copy properties of other ViewStyle to this.</summary>
+        /// <param name="other">The other BindableProperty merge to this.</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public virtual void CopyFrom(BindableObject other)
+        {
+            if (null == other) return;
+
+            Type type1 = this.GetType();
+            BindableProperty.GetBindablePropertysOfType(type1, out var nameToBindableProperty1);
+
+            Type type2 = other.GetType();
+            BindableProperty.GetBindablePropertysOfType(type2, out var nameToBindableProperty2);
+
+            if (null != nameToBindableProperty1)
+            {
+                foreach (KeyValuePair<string, BindableProperty> keyValuePair in nameToBindableProperty1)
+                {
+                    nameToBindableProperty2.TryGetValue(keyValuePair.Key, out var bindableProperty);
+
+                    if (null != bindableProperty && other.IsSet(bindableProperty))
+                    {
+                        object value = other.GetValue(bindableProperty);
+                        InternalSetValue(keyValuePair.Value, value);
+                    }
+                }
+            }
+        }
+
+        /// <summary>
+        /// Copy all binding from other object.
+        /// </summary>
+        /// <param name="other"></param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public void CopyBindingRelationShip(BindableObject other)
+        {
+            if (null == other)
+            {
+                return;
+            }
+
+            foreach (var property in properties)
+            {
+                RemoveBinding(property.Key);
+            }
+
+            foreach (var property in other.properties)
+            {
+                if (null != property.Value.Binding)
+                {
+                    var binding = property.Value.Binding;
+                    other.RemoveBinding(property.Key);
+                    SetBinding(property.Key, binding);
+                }
+            }
+        }
 
         /// <summary>
         /// Raised whenever the BindingContext property changes.
         /// </summary>
-               public event EventHandler BindingContextChanged;
+        /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public event EventHandler BindingContextChanged;
 
-               internal void ClearValue(BindableProperty property, bool fromStyle)
-               {
-                       ClearValue(property, fromStyle: fromStyle, checkAccess: true);
-               }
+        internal void ClearValue(BindableProperty property, bool fromStyle) => ClearValue(property, fromStyle: fromStyle, checkAccess: true);
 
         /// <summary>
-        /// Clears any value set by Xamarin.Forms.BindableObject.SetValue.
+        /// Clears any value set by Tizen.NUI.Xaml.BindableObject.SetValue.
         /// </summary>
         /// <param name="property">The BindableProperty to clear</param>
-        public void ClearValue(BindableProperty property)
-               {
-                       ClearValue(property, fromStyle: false, checkAccess: true);
-               }
+        internal void ClearValue(BindableProperty property)
+        {
+            ClearValue(property, fromStyle: false, checkAccess: true);
+        }
 
         /// <summary>
-        /// Clears any value set by Xamarin.Forms.BindableObject.SetValue for the property that is identified by propertyKey.
+        /// Clears any value set by Tizen.NUI.Xaml.BindableObject.SetValue for the property that is identified by propertyKey.
         /// </summary>
         /// <param name="propertyKey">The BindablePropertyKey that identifies the BindableProperty to clear.</param>
-        public void ClearValue(BindablePropertyKey propertyKey)
-               {
-                       if (propertyKey == null)
-                               throw new ArgumentNullException("propertyKey");
+        internal void ClearValue(BindablePropertyKey propertyKey)
+        {
+            if (propertyKey == null)
+                throw new ArgumentNullException(nameof(propertyKey));
 
-                       ClearValue(propertyKey.BindableProperty, fromStyle:false, checkAccess: false);
-               }
+            ClearValue(propertyKey.BindableProperty, fromStyle: false, checkAccess: false);
+        }
 
         /// <summary>
         /// Return true if the target property exists and has been set.
         /// </summary>
         /// <param name="targetProperty">The target property</param>
         /// <returns>return true if the target property exists and has been set</returns>
-               public bool IsSet(BindableProperty targetProperty)
-               {
-                       if (targetProperty == null)
-                               throw new ArgumentNullException(nameof(targetProperty));
+        internal bool IsSet(BindableProperty targetProperty)
+        {
+            if (targetProperty == null)
+                throw new ArgumentNullException(nameof(targetProperty));
 
-                       var bpcontext = GetContext(targetProperty);
-                       return bpcontext != null
-                               && (bpcontext.Attributes & BindableContextAttributes.IsDefaultValue) == 0;
-               }
+            var bpcontext = GetContext(targetProperty);
+            return bpcontext != null
+                && (bpcontext.Attributes & BindableContextAttributes.IsDefaultValue) == 0;
+        }
 
         /// <summary>
         /// Returns the value that is contained the BindableProperty.
         /// </summary>
         /// <param name="property">The BindableProperty for which to get the value.</param>
         /// <returns>The value that is contained the BindableProperty</returns>
-               public object GetValue(BindableProperty property)
-               {
-                       if (property == null)
-                               throw new ArgumentNullException("property");
+        /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public object GetValue(BindableProperty property)
+        {
+            if (property == null)
+                throw new ArgumentNullException(nameof(property));
+
+            if (!IsBound && property.ValueGetter != null)
+            {
+                return property.ValueGetter(this);
+            }
 
-                       BindablePropertyContext context = property.DefaultValueCreator != null ? GetOrCreateContext(property) : GetContext(property);
+            BindablePropertyContext context = property.DefaultValueCreator != null ? GetOrCreateContext(property) : GetContext(property);
 
-                       if (context == null)
-                               return property.DefaultValue;
+            if (context == null)
+                return property.DefaultValue;
 
-                       return context.Value;
-               }
+            return context.Value;
+        }
 
         /// <summary>
         /// Raised when a property is about to change.
         /// </summary>
-               public event PropertyChangingEventHandler PropertyChanging;
+        /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public event PropertyChangingEventHandler PropertyChanging;
 
         /// <summary>
         /// Removes a previously set binding.
         /// </summary>
         /// <param name="property">The BindableProperty from which to remove bindings.</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
         public void RemoveBinding(BindableProperty property)
-               {
-                       if (property == null)
-                               throw new ArgumentNullException("property");
+        {
+            if (property == null)
+                throw new ArgumentNullException(nameof(property));
 
-                       BindablePropertyContext context = GetContext(property);
-                       if (context == null || context.Binding == null)
-                               return;
+            BindablePropertyContext context = GetContext(property);
+            if (context == null || context.Binding == null)
+                return;
 
-                       RemoveBinding(property, context);
-               }
+            RemoveBinding(property, context);
+        }
 
         /// <summary>
         /// Assigns a binding to a property.
         /// </summary>
         /// <param name="targetProperty">The BindableProperty on which to set a binding.</param>
         /// <param name="binding">The binding to set.</param>
-        public void SetBinding(BindableProperty targetProperty, BindingBase binding)
-               {
-                       SetBinding(targetProperty, binding, false);
-               }
+        /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public void SetBinding(BindableProperty targetProperty, BindingBase binding) => SetBinding(targetProperty, binding, false);
+
+        /// Internal used, will never changed to not hidden.
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public virtual bool IsCreateByXaml
+        {
+            get;
+            set;
+        }
+
+        /// This will be public opened in next ACR.
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public void EnforceNotifyBindedInstance(BindableProperty property)
+        {
+            if (null != property)
+            {
+                BindablePropertyContext context = GetOrCreateContext(property);
+                BindingBase binding = context.Binding;
+
+                var currentlyApplying = applying;
+
+                if (binding != null && !currentlyApplying)
+                {
+                    applying = true;
+                    binding.Apply(true);
+                    applying = false;
+                }
+
+                OnPropertyChanged(property.PropertyName);
+
+                PropertyToGroup.TryGetValue(property, out HashSet<BindableProperty> propertyGroup);
+
+                if (null != propertyGroup)
+                {
+                    foreach (var relativeProperty in propertyGroup)
+                    {
+                        if (relativeProperty != property)
+                        {
+                            var relativeContext = GetOrCreateContext(relativeProperty);
+                            var relativeBinding = relativeContext.Binding;
+
+                            if (null != relativeBinding)
+                            {
+                                applying = true;
+                                relativeBinding.Apply(true);
+                                applying = false;
+                            }
+
+                            OnPropertyChanged(relativeProperty.PropertyName);
+                        }
+                    }
+                }
+            }
+        }
 
         /// <summary>
         /// Sets the value of the specified property.
         /// </summary>
         /// <param name="property">The BindableProperty on which to assign a value.</param>
         /// <param name="value">The value to set.</param>
-               public void SetValue(BindableProperty property, object value)
-               {
-                       SetValue(property, value, false, true);
-               }
+        /// <exception cref="ArgumentNullException"> Thrown when property is null. </exception>
+        /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public void SetValue(BindableProperty property, object value)
+        {
+            InternalSetValue(property, value);
+            ChangedPropertiesSetExcludingStyle.Add(property);
+        }
+
+        internal void InternalSetValue(BindableProperty property, object value)
+        {
+            if (true == IsBound)
+            {
+                SetValue(property, value, false, true);
+            }
+            else
+            {
+                if (null == property)
+                {
+                    throw new ArgumentNullException(nameof(property));
+                }
+
+                object oldvalue = null;
+                BindablePropertyContext context = GetOrCreateContext(property);
+                if (null != context)
+                {
+                    context.Attributes |= BindableContextAttributes.IsManuallySet;
+                    oldvalue = context.Value;
+                    context.Value = value;
+                }
+
+                property.PropertyChanging?.Invoke(this, oldvalue, value);
+                property.PropertyChanged?.Invoke(this, oldvalue, value);
+
+                OnPropertyChanged(property.PropertyName);
+                OnPropertyChangedWithData(property);
+            }
+        }
+
+        private HashSet<BindableProperty> changedPropertiesSetExcludingStyle;
+        internal protected HashSet<BindableProperty> ChangedPropertiesSetExcludingStyle
+        {
+            get
+            {
+                if (null == changedPropertiesSetExcludingStyle)
+                {
+                    changedPropertiesSetExcludingStyle = new HashSet<BindableProperty>();
+                }
+
+                return changedPropertiesSetExcludingStyle;
+            }
+        }
 
         /// <summary>
         /// Sets the value of the propertyKey.
         /// </summary>
         /// <param name="propertyKey">The BindablePropertyKey on which to assign a value.</param>
         /// <param name="value">The value to set.</param>
-               public void SetValue(BindablePropertyKey propertyKey, object value)
-               {
-                       if (propertyKey == null)
-                               throw new ArgumentNullException("propertyKey");
+        /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public void SetValue(BindablePropertyKey propertyKey, object value)
+        {
+            if (propertyKey == null)
+                throw new ArgumentNullException(nameof(propertyKey));
 
-                       SetValue(propertyKey.BindableProperty, value, false, false);
-               }
+            SetValue(propertyKey.BindableProperty, value, false, false);
+        }
 
         /// <summary>
         /// Set the inherited context to a neated element.
         /// </summary>
         /// <param name="bindable">The object on which to set the inherited binding context.</param>
         /// <param name="value">The inherited context to set.</param>
-               [EditorBrowsable(EditorBrowsableState.Never)]
-               public static void SetInheritedBindingContext(BindableObject bindable, object value)
-               {
-                       BindablePropertyContext bpContext = bindable.GetContext(BindingContextProperty);
-                       if (bpContext != null && ((bpContext.Attributes & BindableContextAttributes.IsManuallySet) != 0))
-                               return;
-
-                       object oldContext = bindable._inheritedContext;
-
-                       if (ReferenceEquals(oldContext, value))
-                               return;
-
-                       if (bpContext != null && oldContext == null)
-                               oldContext = bpContext.Value;
-
-                       if (bpContext != null && bpContext.Binding != null)
-                       {
-                               bpContext.Binding.Context = value;
-                               bindable._inheritedContext = null;
-                       }
-                       else
-                       {
-                               bindable._inheritedContext = value;
-                       }
-
-                       bindable.ApplyBindings(skipBindingContext:false, fromBindingContextChanged:true);
-                       bindable.OnBindingContextChanged();
-               }
+        /// <exception cref="ArgumentNullException"> Thrown when bindable is null. </exception>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static void SetInheritedBindingContext(BindableObject bindable, object value)
+        {
+            if (null == bindable)
+            {
+                throw new ArgumentNullException(nameof(bindable));
+            }
+
+            BindablePropertyContext bpContext = bindable.GetContext(BindingContextProperty);
+            if (bpContext != null && ((bpContext.Attributes & BindableContextAttributes.IsManuallySet) != 0))
+                return;
+
+            object oldContext = bindable.inheritedContext;
+
+            if (ReferenceEquals(oldContext, value))
+                return;
+
+            if (bpContext != null && oldContext == null)
+                oldContext = bpContext.Value;
+
+            if (bpContext != null && bpContext.Binding != null)
+            {
+                bpContext.Binding.Context = value;
+                bindable.inheritedContext = null;
+            }
+            else
+            {
+                bindable.inheritedContext = value;
+            }
+
+            bindable.ApplyBindings(skipBindingContext: false, fromBindingContextChanged: true);
+            bindable.OnBindingContextChanged();
+        }
 
         /// <summary>
+        /// Register the properties which can effect each other in Binding to same group.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static void RegisterPropertyGroup(BindableProperty property, HashSet<BindableProperty> group)
+        {
+            if (!PropertyToGroup.ContainsKey(property))
+            {
+                PropertyToGroup.Add(property, group);
+            }
+
+            if (null != group && !(group.Contains(property)))
+            {
+                group.Add(property);
+            }
+        }
+        /// <summary>
         /// Apply the bindings to BindingContext.
         /// </summary>
-               protected void ApplyBindings()
-               {
-                       ApplyBindings(skipBindingContext: false, fromBindingContextChanged: false);
-               }
+        /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        protected void ApplyBindings() => ApplyBindings(skipBindingContext: false, fromBindingContextChanged: false);
 
         /// <summary>
         /// Override this method to execute an action when the BindingContext changes.
         /// </summary>
-               protected virtual void OnBindingContextChanged()
-               {
-                       BindingContextChanged?.Invoke(this, EventArgs.Empty);
-               }
+        /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        protected virtual void OnBindingContextChanged()
+        {
+            BindingContextChanged?.Invoke(this, EventArgs.Empty);
+        }
 
         /// <summary>
         /// Call this method from a child class to notify that a change happened on a property.
         /// </summary>
         /// <param name="propertyName">The name of the property that changed.</param>
+        /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
+        [EditorBrowsable(EditorBrowsableState.Never)]
         protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
-                       => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
+            => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
 
         /// <summary>
         /// Call this method from a child class to notify that a change is going to happen on a property.
         /// </summary>
         /// <param name="propertyName">The name of the property that is changing.</param>
-               protected virtual void OnPropertyChanging([CallerMemberName] string propertyName = null)
-                       => PropertyChanging?.Invoke(this, new PropertyChangingEventArgs(propertyName));
+        /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        protected virtual void OnPropertyChanging([CallerMemberName] string propertyName = null)
+            => PropertyChanging?.Invoke(this, new PropertyChangingEventArgs(propertyName));
+        
+        /// <summary>
+        /// Method that is called when a bound property is changed.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        protected virtual void OnPropertyChangedWithData(BindableProperty prop) { }
 
         /// <summary>
         /// Unapplies all previously set bindings.
         /// </summary>
-               protected void UnapplyBindings()
-               {
-                       for (int i = 0, _propertiesCount = _properties.Count; i < _propertiesCount; i++) {
-                               BindablePropertyContext context = _properties [i];
-                               if (context.Binding == null)
-                                       continue;
-
-                               context.Binding.Unapply();
-                       }
-               }
-
-               internal bool GetIsBound(BindableProperty targetProperty)
-               {
-                       if (targetProperty == null)
-                               throw new ArgumentNullException("targetProperty");
-
-                       BindablePropertyContext bpcontext = GetContext(targetProperty);
-                       return bpcontext != null && bpcontext.Binding != null;
-               }
+        /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        protected void UnapplyBindings()
+        {
+            foreach (var context in properties.Values)
+            {
+                if (context.Binding == null)
+                    continue;
+
+                context.Binding.Unapply();
+            }
+        }
+
+        internal bool GetIsBound(BindableProperty targetProperty)
+        {
+            if (targetProperty == null)
+                throw new ArgumentNullException(nameof(targetProperty));
+
+            BindablePropertyContext bpcontext = GetContext(targetProperty);
+            return bpcontext != null && bpcontext.Binding != null;
+        }
 
         /// <summary>
         /// Returns the value that is contained the BindableProperty.
@@ -255,37 +483,34 @@ namespace Tizen.NUI.Binding
         /// <param name="property0">The BindableProperty instance.</param>
         /// <param name="property1">The BindableProperty instance.</param>
         /// <returns>The value that is contained the BindableProperty</returns>
-               [EditorBrowsable(EditorBrowsableState.Never)]
-               public object[] GetValues(BindableProperty property0, BindableProperty property1)
-               {
-                       var values = new object[2];
-
-                       for (var i = 0; i < _properties.Count; i++)
-                       {
-                               BindablePropertyContext context = _properties[i];
-
-                               if (ReferenceEquals(context.Property, property0))
-                               {
-                                       values[0] = context.Value;
-                                       property0 = null;
-                               }
-                               else if (ReferenceEquals(context.Property, property1))
-                               {
-                                       values[1] = context.Value;
-                                       property1 = null;
-                               }
-
-                               if (property0 == null && property1 == null)
-                                       return values;
-                       }
-
-                       if (!ReferenceEquals(property0, null))
-                               values[0] = property0.DefaultValueCreator == null ? property0.DefaultValue : CreateAndAddContext(property0).Value;
-                       if (!ReferenceEquals(property1, null))
-                               values[1] = property1.DefaultValueCreator == null ? property1.DefaultValue : CreateAndAddContext(property1).Value;
-
-                       return values;
-               }
+        internal object[] GetValues(BindableProperty property0, BindableProperty property1)
+        {
+            var values = new object[2];
+
+            foreach (var context in properties.Values)
+            {
+                if (ReferenceEquals(context.Property, property0))
+                {
+                    values[0] = context.Value;
+                    property0 = null;
+                }
+                else if (ReferenceEquals(context.Property, property1))
+                {
+                    values[1] = context.Value;
+                    property1 = null;
+                }
+
+                if (property0 == null && property1 == null)
+                    return values;
+            }
+
+            if (!ReferenceEquals(property0, null))
+                values[0] = property0.DefaultValueCreator == null ? property0.DefaultValue : CreateAndAddContext(property0).Value;
+            if (!ReferenceEquals(property1, null))
+                values[1] = property1.DefaultValueCreator == null ? property1.DefaultValue : CreateAndAddContext(property1).Value;
+
+            return values;
+        }
 
         /// <summary>
         /// Returns the value that is contained the BindableProperty.
@@ -294,162 +519,155 @@ namespace Tizen.NUI.Binding
         /// <param name="property1">The BindableProperty instance.</param>
         /// <param name="property2">The BindableProperty instance.</param>
         /// <returns>The value that is contained the BindableProperty</returns>
-               [EditorBrowsable(EditorBrowsableState.Never)]
-               public object[] GetValues(BindableProperty property0, BindableProperty property1, BindableProperty property2)
-               {
-                       var values = new object[3];
-
-                       for (var i = 0; i < _properties.Count; i++)
-                       {
-                               BindablePropertyContext context = _properties[i];
-
-                               if (ReferenceEquals(context.Property, property0))
-                               {
-                                       values[0] = context.Value;
-                                       property0 = null;
-                               }
-                               else if (ReferenceEquals(context.Property, property1))
-                               {
-                                       values[1] = context.Value;
-                                       property1 = null;
-                               }
-                               else if (ReferenceEquals(context.Property, property2))
-                               {
-                                       values[2] = context.Value;
-                                       property2 = null;
-                               }
-
-                               if (property0 == null && property1 == null && property2 == null)
-                                       return values;
-                       }
-
-                       if (!ReferenceEquals(property0, null))
-                               values[0] = property0.DefaultValueCreator == null ? property0.DefaultValue : CreateAndAddContext(property0).Value;
-                       if (!ReferenceEquals(property1, null))
-                               values[1] = property1.DefaultValueCreator == null ? property1.DefaultValue : CreateAndAddContext(property1).Value;
-                       if (!ReferenceEquals(property2, null))
-                               values[2] = property2.DefaultValueCreator == null ? property2.DefaultValue : CreateAndAddContext(property2).Value;
-
-                       return values;
-               }
+        internal object[] GetValues(BindableProperty property0, BindableProperty property1, BindableProperty property2)
+        {
+            var values = new object[3];
+
+            foreach (var context in properties.Values)
+            {
+                if (ReferenceEquals(context.Property, property0))
+                {
+                    values[0] = context.Value;
+                    property0 = null;
+                }
+                else if (ReferenceEquals(context.Property, property1))
+                {
+                    values[1] = context.Value;
+                    property1 = null;
+                }
+                else if (ReferenceEquals(context.Property, property2))
+                {
+                    values[2] = context.Value;
+                    property2 = null;
+                }
+
+                if (property0 == null && property1 == null && property2 == null)
+                    return values;
+            }
+
+            if (!ReferenceEquals(property0, null))
+                values[0] = property0.DefaultValueCreator == null ? property0.DefaultValue : CreateAndAddContext(property0).Value;
+            if (!ReferenceEquals(property1, null))
+                values[1] = property1.DefaultValueCreator == null ? property1.DefaultValue : CreateAndAddContext(property1).Value;
+            if (!ReferenceEquals(property2, null))
+                values[2] = property2.DefaultValueCreator == null ? property2.DefaultValue : CreateAndAddContext(property2).Value;
+
+            return values;
+        }
 
         /// <summary>
         /// Returns the value that is contained the BindableProperty.
         /// </summary>
         /// <param name="properties">The array of the BindableProperty instances</param>
         /// <returns>The values that is contained the BindableProperty instances.</returns>
-               [EditorBrowsable(EditorBrowsableState.Never)]
-               internal object[] GetValues(params BindableProperty[] properties)
-               {
-                       var values = new object[properties.Length];
-                       for (var i = 0; i < _properties.Count; i++) {
-                               var context = _properties[i];
-                               var index = properties.IndexOf(context.Property);
-                               if (index < 0)
-                                       continue;
-                               values[index] = context.Value;
-                       }
-                       for (var i = 0; i < values.Length; i++) {
-                               if (!ReferenceEquals(values[i], null))
-                                       continue;
-                               values[i] = properties[i].DefaultValueCreator == null ? properties[i].DefaultValue : CreateAndAddContext(properties[i]).Value;
-                       }
-                       return values;
-               }
-
-               internal virtual void OnRemoveDynamicResource(BindableProperty property)
-               {
-               }
-
-               internal virtual void OnSetDynamicResource(BindableProperty property, string key)
-               {
-               }
-
-               internal void RemoveDynamicResource(BindableProperty property)
-               {
-                       if (property == null)
-                               throw new ArgumentNullException("property");
-
-                       OnRemoveDynamicResource(property);
-                       BindablePropertyContext context = GetOrCreateContext(property);
-                       context.Attributes &= ~BindableContextAttributes.IsDynamicResource;
-               }
-
-               internal void SetBinding(BindableProperty targetProperty, BindingBase binding, bool fromStyle)
-               {
-                       if (targetProperty == null)
-                               throw new ArgumentNullException("targetProperty");
-                       if (binding == null)
-                               throw new ArgumentNullException("binding");
-
-                       if (fromStyle && !CanBeSetFromStyle(targetProperty))
-                               return;
-
-                       var context = GetOrCreateContext(targetProperty);
-                       if (fromStyle)
-                               context.Attributes |= BindableContextAttributes.IsSetFromStyle;
-                       else
-                               context.Attributes &= ~BindableContextAttributes.IsSetFromStyle;
-
-                       if (context.Binding != null)
-                               context.Binding.Unapply();
-
-                       BindingBase oldBinding = context.Binding;
-                       context.Binding = binding;
-
-                       targetProperty.BindingChanging?.Invoke(this, oldBinding, binding);
-
-                       binding.Apply(BindingContext, this, targetProperty);
-               }
-
-               bool CanBeSetFromStyle(BindableProperty property)
-               {
-                       var context = GetContext(property);
-                       if (context == null)
-                               return true;
-                       if ((context.Attributes & BindableContextAttributes.IsSetFromStyle) == BindableContextAttributes.IsSetFromStyle)
-                               return true;
-                       if ((context.Attributes & BindableContextAttributes.IsDefaultValue) == BindableContextAttributes.IsDefaultValue)
-                               return true;
-                       if ((context.Attributes & BindableContextAttributes.IsDefaultValueCreated) == BindableContextAttributes.IsDefaultValueCreated)
-                               return true;
-                       return false;
-               }
-
-               internal void SetDynamicResource(BindableProperty property, string key)
-               {
-                       SetDynamicResource(property, key, false);
-               }
-
-               internal void SetDynamicResource(BindableProperty property, string key, bool fromStyle)
-               {
-                       if (property == null)
-                               throw new ArgumentNullException(nameof(property));
-                       if (string.IsNullOrEmpty(key))
-                               throw new ArgumentNullException(nameof(key));
-                       if (fromStyle && !CanBeSetFromStyle(property))
-                               return;
-
-                       var context = GetOrCreateContext(property);
-
-                       context.Attributes |= BindableContextAttributes.IsDynamicResource;
-                       if (fromStyle)
-                               context.Attributes |= BindableContextAttributes.IsSetFromStyle;
-                       else
-                               context.Attributes &= ~BindableContextAttributes.IsSetFromStyle;
-
-                       OnSetDynamicResource(property, key);
-               }
-
-               internal void SetValue(BindableProperty property, object value, bool fromStyle)
-               {
-                       SetValue(property, value, fromStyle, true);
-               }
-
-               internal void SetValueCore(BindablePropertyKey propertyKey, object value, SetValueFlags attributes = SetValueFlags.None)
-               {
-                       SetValueCore(propertyKey.BindableProperty, value, attributes, SetValuePrivateFlags.None);
-               }
+        internal object[] GetValues(params BindableProperty[] properties)
+        {
+            var values = new object[properties.Length];
+            foreach (var context in this.properties.Values)
+            {
+                var index = properties.IndexOf(context.Property);
+                if (index < 0)
+                    continue;
+                values[index] = context.Value;
+            }
+            for (var i = 0; i < values.Length; i++)
+            {
+                if (!ReferenceEquals(values[i], null))
+                    continue;
+                values[i] = properties[i].DefaultValueCreator == null ? properties[i].DefaultValue : CreateAndAddContext(properties[i]).Value;
+            }
+            return values;
+        }
+
+        internal virtual void OnRemoveDynamicResource(BindableProperty property)
+        {
+        }
+
+        internal virtual void OnSetDynamicResource(BindableProperty property, string key)
+        {
+        }
+
+        internal void RemoveDynamicResource(BindableProperty property)
+        {
+            if (property == null)
+                throw new ArgumentNullException(nameof(property));
+
+            OnRemoveDynamicResource(property);
+            BindablePropertyContext context = GetOrCreateContext(property);
+            context.Attributes &= ~BindableContextAttributes.IsDynamicResource;
+        }
+
+        internal void SetBinding(BindableProperty targetProperty, BindingBase binding, bool fromStyle)
+        {
+            if (targetProperty == null)
+                throw new ArgumentNullException(nameof(targetProperty));
+            if (binding == null)
+                throw new ArgumentNullException(nameof(binding));
+
+            if (fromStyle && !CanBeSetFromStyle(targetProperty))
+                return;
+
+            IsBound = true;
+
+            var context = GetOrCreateContext(targetProperty);
+            if (fromStyle)
+                context.Attributes |= BindableContextAttributes.IsSetFromStyle;
+            else
+                context.Attributes &= ~BindableContextAttributes.IsSetFromStyle;
+
+            if (context.Binding != null)
+                context.Binding.Unapply();
+
+            BindingBase oldBinding = context.Binding;
+            context.Binding = binding;
+
+            targetProperty.BindingChanging?.Invoke(this, oldBinding, binding);
+
+            binding.Apply(BindingContext, this, targetProperty);
+        }
+
+        bool CanBeSetFromStyle(BindableProperty property)
+        {
+            var context = GetContext(property);
+            if (context == null)
+                return true;
+            if ((context.Attributes & BindableContextAttributes.IsSetFromStyle) == BindableContextAttributes.IsSetFromStyle)
+                return true;
+            if ((context.Attributes & BindableContextAttributes.IsDefaultValue) == BindableContextAttributes.IsDefaultValue)
+                return true;
+            if ((context.Attributes & BindableContextAttributes.IsDefaultValueCreated) == BindableContextAttributes.IsDefaultValueCreated)
+                return true;
+            return false;
+        }
+
+        internal void SetDynamicResource(BindableProperty property, string key) => SetDynamicResource(property, key, false);
+
+        internal void SetDynamicResource(BindableProperty property, string key, bool fromStyle)
+        {
+            if (property == null)
+                throw new ArgumentNullException(nameof(property));
+            if (string.IsNullOrEmpty(key))
+                throw new ArgumentNullException(nameof(key));
+            if (fromStyle && !CanBeSetFromStyle(property))
+                return;
+
+            var context = GetOrCreateContext(property);
+
+            context.Attributes |= BindableContextAttributes.IsDynamicResource;
+            if (fromStyle)
+                context.Attributes |= BindableContextAttributes.IsSetFromStyle;
+            else
+                context.Attributes &= ~BindableContextAttributes.IsSetFromStyle;
+
+            OnSetDynamicResource(property, key);
+        }
+
+        internal void SetValue(BindableProperty property, object value, bool fromStyle) => SetValue(property, value, fromStyle, true);
+
+        internal void SetValueCore(BindablePropertyKey propertyKey, object value, SetValueFlags attributes = SetValueFlags.None)
+        {
+            SetValueCore(propertyKey.BindableProperty, value, attributes, SetValuePrivateFlags.None);
+        }
 
         /// <summary>
         /// For internal use.
@@ -457,360 +675,486 @@ namespace Tizen.NUI.Binding
         /// <param name="property">The BindableProperty on which to assign a value.</param>
         /// <param name="value">The value to set</param>
         /// <param name="attributes">The set value flag</param>
-               [EditorBrowsable(EditorBrowsableState.Never)]
-               public void SetValueCore(BindableProperty property, object value, SetValueFlags attributes = SetValueFlags.None)
-               {
-                       SetValueCore(property, value, attributes, SetValuePrivateFlags.Default);
-               }
-
-               internal void SetValueCore(BindableProperty property, object value, SetValueFlags attributes, SetValuePrivateFlags privateAttributes)
-               {
-                       bool checkAccess = (privateAttributes & SetValuePrivateFlags.CheckAccess) != 0;
-                       bool manuallySet = (privateAttributes & SetValuePrivateFlags.ManuallySet) != 0;
-                       bool silent = (privateAttributes & SetValuePrivateFlags.Silent) != 0;
-                       bool fromStyle = (privateAttributes & SetValuePrivateFlags.FromStyle) != 0;
-                       bool converted = (privateAttributes & SetValuePrivateFlags.Converted) != 0;
-
-                       if (property == null)
-                               throw new ArgumentNullException("property");
-                       if (checkAccess && property.IsReadOnly)
-                       {
-                               Debug.WriteLine("Can not set the BindableProperty \"{0}\" because it is readonly.", property.PropertyName);
-                               return;
-                       }
-
-                       if (!converted && !property.TryConvert(ref value))
-                       {
-                               Console.WriteLine("SetValue", "Can not convert {0} to type '{1}'", value, property.ReturnType);
-                               return;
-                       }
-
-                       if (property.ValidateValue != null && !property.ValidateValue(this, value))
-                               throw new ArgumentException("Value was an invalid value for " + property.PropertyName, "value");
-
-                       if (property.CoerceValue != null)
-                               value = property.CoerceValue(this, value);
-
-                       BindablePropertyContext context = GetOrCreateContext(property);
-                       if (manuallySet) {
-                               context.Attributes |= BindableContextAttributes.IsManuallySet;
-                               context.Attributes &= ~BindableContextAttributes.IsSetFromStyle;
-                       } else
-                               context.Attributes &= ~BindableContextAttributes.IsManuallySet;
-
-                       if (fromStyle)
-                               context.Attributes |= BindableContextAttributes.IsSetFromStyle;
-                       // else omitted on purpose
-
-                       bool currentlyApplying = _applying;
-
-                       if ((context.Attributes & BindableContextAttributes.IsBeingSet) != 0)
-                       {
-                               Queue<SetValueArgs> delayQueue = context.DelayedSetters;
-                               if (delayQueue == null)
-                                       context.DelayedSetters = delayQueue = new Queue<SetValueArgs>();
-
-                               delayQueue.Enqueue(new SetValueArgs(property, context, value, currentlyApplying, attributes));
-                       }
-                       else
-                       {
-                               context.Attributes |= BindableContextAttributes.IsBeingSet;
-                               SetValueActual(property, context, value, currentlyApplying, attributes, silent);
-
-                               Queue<SetValueArgs> delayQueue = context.DelayedSetters;
-                               if (delayQueue != null)
-                               {
-                                       while (delayQueue.Count > 0)
-                                       {
-                                               SetValueArgs s = delayQueue.Dequeue();
-                                               SetValueActual(s.Property, s.Context, s.Value, s.CurrentlyApplying, s.Attributes);
-                                       }
-
-                                       context.DelayedSetters = null;
-                               }
-
-                               context.Attributes &= ~BindableContextAttributes.IsBeingSet;
-                       }
-               }
-
-               internal void ApplyBindings(bool skipBindingContext, bool fromBindingContextChanged)
-               {
-                       var prop = _properties.ToArray();
-                       for (int i = 0, propLength = prop.Length; i < propLength; i++) {
-                               BindablePropertyContext context = prop [i];
-                               BindingBase binding = context.Binding;
-                               if (binding == null)
-                                       continue;
-
-                               if (skipBindingContext && ReferenceEquals(context.Property, BindingContextProperty))
-                                       continue;
-
-                               binding.Unapply(fromBindingContextChanged: fromBindingContextChanged);
-                               binding.Apply(BindingContext, this, context.Property, fromBindingContextChanged: fromBindingContextChanged);
-                       }
-               }
-
-               static void BindingContextPropertyBindingChanging(BindableObject bindable, BindingBase oldBindingBase, BindingBase newBindingBase)
-               {
-                       object context = bindable._inheritedContext;
-                       var oldBinding = oldBindingBase as Binding;
-                       var newBinding = newBindingBase as Binding;
-
-                       if (context == null && oldBinding != null)
-                               context = oldBinding.Context;
-                       if (context != null && newBinding != null)
-                               newBinding.Context = context;
-               }
-
-               static void BindingContextPropertyChanged(BindableObject bindable, object oldvalue, object newvalue)
-               {
-                       bindable._inheritedContext = null;
-                       bindable.ApplyBindings(skipBindingContext: true, fromBindingContextChanged:true);
-                       bindable.OnBindingContextChanged();
-               }
-
-               void ClearValue(BindableProperty property, bool fromStyle, bool checkAccess)
-               {
-                       if (property == null)
-                               throw new ArgumentNullException(nameof(property));
-
-                       if (checkAccess && property.IsReadOnly)
-                               throw new InvalidOperationException(string.Format("The BindableProperty \"{0}\" is readonly.", property.PropertyName));
-
-                       BindablePropertyContext bpcontext = GetContext(property);
-                       if (bpcontext == null)
-                               return;
-
-                       if (fromStyle && !CanBeSetFromStyle(property))
-                               return;
-
-                       object original = bpcontext.Value;
-
-                       object newValue = property.GetDefaultValue(this);
-
-                       bool same = Equals(original, newValue);
-                       if (!same)
-                       {
-                               property.PropertyChanging?.Invoke(this, original, newValue);
-
-                               OnPropertyChanging(property.PropertyName);
-                       }
-
-                       bpcontext.Attributes &= ~BindableContextAttributes.IsManuallySet;
-                       bpcontext.Value = newValue;
-                       if (property.DefaultValueCreator == null)
-                               bpcontext.Attributes |= BindableContextAttributes.IsDefaultValue;
-                       else
-                               bpcontext.Attributes |= BindableContextAttributes.IsDefaultValueCreated;
-
-                       if (!same)
-                       {
-                               OnPropertyChanged(property.PropertyName);
-                               property.PropertyChanged?.Invoke(this, original, newValue);
-                       }
-               }
-
-               [MethodImpl(MethodImplOptions.AggressiveInlining)]
-               BindablePropertyContext CreateAndAddContext(BindableProperty property)
-               {
-                       var context = new BindablePropertyContext { Property = property, Value = property.DefaultValueCreator != null ? property.DefaultValueCreator(this) : property.DefaultValue };
-
-                       if (property.DefaultValueCreator == null)
-                               context.Attributes = BindableContextAttributes.IsDefaultValue;
-                       else
-                               context.Attributes = BindableContextAttributes.IsDefaultValueCreated;
-
-                       _properties.Add(context);
-                       return context;
-               }
-
-               [MethodImpl(MethodImplOptions.AggressiveInlining)]
-               BindablePropertyContext GetContext(BindableProperty property)
-               {
-                       List<BindablePropertyContext> properties = _properties;
-
-                       for (var i = 0; i < properties.Count; i++)
-                       {
-                               BindablePropertyContext context = properties[i];
-                               if (ReferenceEquals(context.Property, property))
-                                       return context;
-                       }
-
-                       return null;
-               }
-
-               [MethodImpl(MethodImplOptions.AggressiveInlining)]
-               BindablePropertyContext GetOrCreateContext(BindableProperty property)
-               {
-                       BindablePropertyContext context = GetContext(property);
-                       if (context == null)
-                       {
-                               context = CreateAndAddContext(property);
-                       }
-
-                       return context;
-               }
-
-               void RemoveBinding(BindableProperty property, BindablePropertyContext context)
-               {
-                       context.Binding.Unapply();
-
-                       property.BindingChanging?.Invoke(this, context.Binding, null);
-
-                       context.Binding = null;
-               }
-
-               void SetValue(BindableProperty property, object value, bool fromStyle, bool checkAccess)
-               {
-                       if (property == null)
-                               throw new ArgumentNullException("property");
-
-                       if (checkAccess && property.IsReadOnly)
-                               throw new InvalidOperationException(string.Format("The BindableProperty \"{0}\" is readonly.", property.PropertyName));
-
-                       if (fromStyle && !CanBeSetFromStyle(property))
-                               return;
-
-                       SetValueCore(property, value, SetValueFlags.ClearOneWayBindings | SetValueFlags.ClearDynamicResource,
-                               (fromStyle ? SetValuePrivateFlags.FromStyle : SetValuePrivateFlags.ManuallySet) | (checkAccess ? SetValuePrivateFlags.CheckAccess : 0));
-               }
-
-               void SetValueActual(BindableProperty property, BindablePropertyContext context, object value, bool currentlyApplying, SetValueFlags attributes, bool silent = false)
-               {
-                       object original = context.Value;
-                       bool raiseOnEqual = (attributes & SetValueFlags.RaiseOnEqual) != 0;
-                       bool clearDynamicResources = (attributes & SetValueFlags.ClearDynamicResource) != 0;
-                       bool clearOneWayBindings = (attributes & SetValueFlags.ClearOneWayBindings) != 0;
-                       bool clearTwoWayBindings = (attributes & SetValueFlags.ClearTwoWayBindings) != 0;
-
-                       bool same = ReferenceEquals(context.Property, BindingContextProperty) ? ReferenceEquals(value, original) : Equals(value, original);
-                       if (!silent && (!same || raiseOnEqual))
-                       {
-                               property.PropertyChanging?.Invoke(this, original, value);
-
-                               OnPropertyChanging(property.PropertyName);
-                       }
-
-                       if (!same || raiseOnEqual)
-                       {
-                               context.Value = value;
-                       }
-
-                       context.Attributes &= ~BindableContextAttributes.IsDefaultValue;
-                       context.Attributes &= ~BindableContextAttributes.IsDefaultValueCreated;
-
-                       if ((context.Attributes & BindableContextAttributes.IsDynamicResource) != 0 && clearDynamicResources)
-                               RemoveDynamicResource(property);
-
-                       BindingBase binding = context.Binding;
-                       if (binding != null)
-                       {
-                               if (clearOneWayBindings && binding.GetRealizedMode(property) == BindingMode.OneWay || clearTwoWayBindings && binding.GetRealizedMode(property) == BindingMode.TwoWay)
-                               {
-                                       RemoveBinding(property, context);
-                                       binding = null;
-                               }
-                       }
-
-                       if (!silent && (!same || raiseOnEqual))
-                       {
-                               if (binding != null && !currentlyApplying)
-                               {
-                                       _applying = true;
-                                       binding.Apply(true);
-                                       _applying = false;
-                               }
-
-                               OnPropertyChanged(property.PropertyName);
-
-                               property.PropertyChanged?.Invoke(this, original, value);
-                       }
-               }
-
-               [Flags]
-               enum BindableContextAttributes
-               {
-                       IsManuallySet = 1 << 0,
-                       IsBeingSet = 1 << 1,
-                       IsDynamicResource = 1 << 2,
-                       IsSetFromStyle = 1 << 3,
-                       IsDefaultValue = 1 << 4,
-                       IsDefaultValueCreated = 1 << 5,
-               }
-
-               class BindablePropertyContext
-               {
-                       public BindableContextAttributes Attributes;
-                       public BindingBase Binding;
-                       public Queue<SetValueArgs> DelayedSetters;
-                       public BindableProperty Property;
-                       public object Value;
-               }
-
-               [Flags]
-               internal enum SetValuePrivateFlags
-               {
-                       None = 0,
-                       CheckAccess = 1 << 0,
-                       Silent = 1 << 1,
-                       ManuallySet = 1 << 2,
-                       FromStyle = 1 << 3,
-                       Converted = 1 << 4,
-                       Default = CheckAccess
-               }
-
-               class SetValueArgs
-               {
-                       public readonly SetValueFlags Attributes;
-                       public readonly BindablePropertyContext Context;
-                       public readonly bool CurrentlyApplying;
-                       public readonly BindableProperty Property;
-                       public readonly object Value;
-
-                       public SetValueArgs(BindableProperty property, BindablePropertyContext context, object value, bool currentlyApplying, SetValueFlags attributes)
-                       {
-                               Property = property;
-                               Context = context;
-                               Value = value;
-                               CurrentlyApplying = currentlyApplying;
-                               Attributes = attributes;
-                       }
-               }
-       }
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        internal void SetValueCore(BindableProperty property, object value, SetValueFlags attributes = SetValueFlags.None) => SetValueCore(property, value, attributes, SetValuePrivateFlags.Default);
+
+        internal void SetValueCore(BindableProperty property, object value, SetValueFlags attributes, SetValuePrivateFlags privateAttributes)
+        {
+            bool checkAccess = (privateAttributes & SetValuePrivateFlags.CheckAccess) != 0;
+            bool manuallySet = (privateAttributes & SetValuePrivateFlags.ManuallySet) != 0;
+            bool silent = (privateAttributes & SetValuePrivateFlags.Silent) != 0;
+            bool fromStyle = (privateAttributes & SetValuePrivateFlags.FromStyle) != 0;
+            bool converted = (privateAttributes & SetValuePrivateFlags.Converted) != 0;
+
+            if (property == null)
+                throw new ArgumentNullException(nameof(property));
+            if (checkAccess && property.IsReadOnly)
+            {
+                Debug.WriteLine("Can not set the BindableProperty \"{0}\" because it is readonly.", property.PropertyName);
+                return;
+            }
+
+            if (!converted && !property.TryConvert(ref value))
+            {
+                Console.WriteLine($"SetValue : Can not convert {value} to type {property.ReturnType}");
+                return;
+            }
+
+            if (property.ValidateValue != null && !property.ValidateValue(this, value))
+                throw new ArgumentException("Value was an invalid value for " + property.PropertyName, nameof(value));
+
+            if (property.CoerceValue != null)
+                value = property.CoerceValue(this, value);
+
+            BindablePropertyContext context = GetOrCreateContext(property);
+            if (manuallySet)
+            {
+                context.Attributes |= BindableContextAttributes.IsManuallySet;
+                context.Attributes &= ~BindableContextAttributes.IsSetFromStyle;
+            }
+            else
+            {
+                context.Attributes &= ~BindableContextAttributes.IsManuallySet;
+            }
+
+            if (fromStyle)
+            {
+                context.Attributes |= BindableContextAttributes.IsSetFromStyle;
+            }
+            // else omitted on purpose
+
+            bool currentlyApplying = applying;
+
+            if ((context.Attributes & BindableContextAttributes.IsBeingSet) != 0)
+            {
+                Queue<SetValueArgs> delayQueue = context.DelayedSetters;
+                if (delayQueue == null)
+                    context.DelayedSetters = delayQueue = new Queue<SetValueArgs>();
+
+                delayQueue.Enqueue(new SetValueArgs(property, context, value, currentlyApplying, attributes));
+            }
+            else
+            {
+                context.Attributes |= BindableContextAttributes.IsBeingSet;
+                SetValueActual(property, context, value, currentlyApplying, attributes, silent);
+
+                Queue<SetValueArgs> delayQueue = context.DelayedSetters;
+                if (delayQueue != null)
+                {
+                    while (delayQueue.Count > 0)
+                    {
+                        SetValueArgs s = delayQueue.Dequeue();
+                        SetValueActual(s.Property, s.Context, s.Value, s.CurrentlyApplying, s.Attributes);
+                    }
+
+                    context.DelayedSetters = null;
+                }
+
+                context.Attributes &= ~BindableContextAttributes.IsBeingSet;
+            }
+        }
+
+        internal void ApplyBindings(bool skipBindingContext, bool fromBindingContextChanged)
+        {
+            var prop = properties.Values.ToArray();
+            for (int i = 0, propLength = prop.Length; i < propLength; i++)
+            {
+                BindablePropertyContext context = prop[i];
+                BindingBase binding = context.Binding;
+                if (binding == null)
+                    continue;
+
+                if (skipBindingContext && ReferenceEquals(context.Property, BindingContextProperty))
+                    continue;
+
+                binding.Unapply(fromBindingContextChanged: fromBindingContextChanged);
+                binding.Apply(BindingContext, this, context.Property, fromBindingContextChanged: fromBindingContextChanged);
+            }
+        }
+
+        /// <summary>
+        /// Check if object is bound or not.
+        /// This API used for legacy codes.
+        /// Should be removed after all app usage replaced into IsBound.
+        /// </summary>
+        [Obsolete("This has been deprecated in API11. Use IsBound property instead.")]
+        internal bool IsBinded
+        {
+            get
+            {
+                return IsBound;
+            }
+            set
+            {
+                IsBound = value;
+            }
+        }
+
+        /// <summary>
+        /// Check if object is bound or not.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public bool IsBound
+        {
+            get;
+            set;
+        } = false;
+
+        static void BindingContextPropertyChanged(BindableObject bindable, object oldvalue, object newvalue)
+        {
+            bindable.inheritedContext = null;
+            bindable.ApplyBindings(skipBindingContext: true, fromBindingContextChanged: true);
+            bindable.OnBindingContextChanged();
+
+            if (newvalue is BindableObject targetBindableObject)
+            {
+                targetBindableObject.IsBound = true;
+            }
+        }
+
+        static void BindingContextPropertyBindingChanging(BindableObject bindable, BindingBase oldBindingBase, BindingBase newBindingBase)
+        {
+            object context = bindable.inheritedContext;
+            var oldBinding = oldBindingBase as Binding;
+            var newBinding = newBindingBase as Binding;
+
+            if (context == null && oldBinding != null)
+                context = oldBinding.Context;
+            if (context != null && newBinding != null)
+                newBinding.Context = context;
+        }
+
+        void ClearValue(BindableProperty property, bool fromStyle, bool checkAccess)
+        {
+            if (property == null)
+                throw new ArgumentNullException(nameof(property));
+
+            if (checkAccess && property.IsReadOnly)
+                throw new InvalidOperationException(string.Format("The BindableProperty \"{0}\" is readonly.", property.PropertyName));
+
+            BindablePropertyContext bpcontext = GetContext(property);
+            if (bpcontext == null)
+                return;
+
+            if (fromStyle && !CanBeSetFromStyle(property))
+                return;
+
+            object original = bpcontext.Value;
+
+            object newValue = property.GetDefaultValue(this);
+
+            bool same = Equals(original, newValue);
+            if (!same)
+            {
+                property.PropertyChanging?.Invoke(this, original, newValue);
+
+                OnPropertyChanging(property.PropertyName);
+            }
+
+            bpcontext.Attributes &= ~BindableContextAttributes.IsManuallySet;
+            bpcontext.Value = newValue;
+            if (property.DefaultValueCreator == null)
+                bpcontext.Attributes |= BindableContextAttributes.IsDefaultValue;
+            else
+                bpcontext.Attributes |= BindableContextAttributes.IsDefaultValueCreated;
+
+            if (!same)
+            {
+                OnPropertyChanged(property.PropertyName);
+                OnPropertyChangedWithData(property);
+                property.PropertyChanged?.Invoke(this, original, newValue);
+            }
+        }
+
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        BindablePropertyContext CreateAndAddContext(BindableProperty property)
+        {
+            var context = new BindablePropertyContext { Property = property, Value = property.DefaultValueCreator != null ? property.DefaultValueCreator(this) : property.DefaultValue };
+
+            if (property.DefaultValueCreator == null)
+                context.Attributes = BindableContextAttributes.IsDefaultValue;
+            else
+                context.Attributes = BindableContextAttributes.IsDefaultValueCreated;
+
+            properties.Add(property, context);
+            return context;
+        }
+
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        BindablePropertyContext GetContext(BindableProperty property) => properties.TryGetValue(property, out var result) ? result : null;
+
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        BindablePropertyContext GetOrCreateContext(BindableProperty property)
+        {
+            BindablePropertyContext context = GetContext(property);
+            if (context == null)
+            {
+                context = CreateAndAddContext(property);
+            }
+            else if (property.ValueGetter != null)
+            {
+                context.Value = property.ValueGetter(this); //Update Value from dali
+            }//added by xiaohui.fang
+            else if (property.DefaultValueCreator != null) //This will be removed in the future.
+            {
+                context.Value = property.DefaultValueCreator(this); //Update Value from dali
+            }//added by xb.teng
+
+            return context;
+        }
+
+        void RemoveBinding(BindableProperty property, BindablePropertyContext context)
+        {
+            context.Binding.Unapply();
+
+            property.BindingChanging?.Invoke(this, context.Binding, null);
+
+            context.Binding = null;
+        }
+
+        internal void SetValue(BindableProperty property, object value, bool fromStyle, bool checkAccess)
+        {
+            if (property == null)
+                throw new ArgumentNullException(nameof(property));
+
+            if (checkAccess && property.IsReadOnly)
+                throw new InvalidOperationException(string.Format("The BindableProperty \"{0}\" is readonly.", property.PropertyName));
+
+            if (fromStyle && !CanBeSetFromStyle(property))
+                return;
+
+            SetValueCore(property, value, SetValueFlags.ClearOneWayBindings | SetValueFlags.ClearDynamicResource,
+                (fromStyle ? SetValuePrivateFlags.FromStyle : SetValuePrivateFlags.ManuallySet) | (checkAccess ? SetValuePrivateFlags.CheckAccess : 0));
+        }
+
+        void SetValueActual(BindableProperty property, BindablePropertyContext context, object value, bool currentlyApplying, SetValueFlags attributes, bool silent = false)
+        {
+            object original = context.Value;
+            bool raiseOnEqual = (attributes & SetValueFlags.RaiseOnEqual) != 0;
+            bool clearDynamicResources = (attributes & SetValueFlags.ClearDynamicResource) != 0;
+            bool clearOneWayBindings = (attributes & SetValueFlags.ClearOneWayBindings) != 0;
+            bool clearTwoWayBindings = (attributes & SetValueFlags.ClearTwoWayBindings) != 0;
+
+            bool same = ReferenceEquals(context.Property, BindingContextProperty) ? ReferenceEquals(value, original) : Equals(value, original);
+            if (!silent && (!same || raiseOnEqual))
+            {
+                property.PropertyChanging?.Invoke(this, original, value);
+
+                OnPropertyChanging(property.PropertyName);
+            }
+
+            if (!same || raiseOnEqual)
+            {
+                context.Value = value;
+            }
+
+            context.Attributes &= ~BindableContextAttributes.IsDefaultValue;
+            context.Attributes &= ~BindableContextAttributes.IsDefaultValueCreated;
+
+            if ((context.Attributes & BindableContextAttributes.IsDynamicResource) != 0 && clearDynamicResources)
+                RemoveDynamicResource(property);
+
+            BindingBase binding = context.Binding;
+            if (binding != null)
+            {
+                if (clearOneWayBindings && binding.GetRealizedMode(property) == BindingMode.OneWay || clearTwoWayBindings && binding.GetRealizedMode(property) == BindingMode.TwoWay)
+                {
+                    RemoveBinding(property, context);
+                    binding = null;
+                }
+            }
+
+            PropertyToGroup.TryGetValue(property, out HashSet<BindableProperty> propertyGroup);
+
+            if (!silent && (!same || raiseOnEqual))
+            {
+                property.PropertyChanged?.Invoke(this, original, value);
+
+                if (binding != null && !currentlyApplying)
+                {
+                    applying = true;
+                    binding.Apply(true);
+                    applying = false;
+                }
+
+                OnPropertyChanged(property.PropertyName);
+
+                if (null != propertyGroup)
+                {
+                    foreach (var relativeProperty in propertyGroup)
+                    {
+                        if (relativeProperty != property)
+                        {
+                            var relativeContext = GetOrCreateContext(relativeProperty);
+                            var relativeBinding = relativeContext.Binding;
+
+                            if (null != relativeBinding)
+                            {
+                                applying = true;
+                                relativeBinding.Apply(true);
+                                applying = false;
+                            }
+
+                            OnPropertyChanged(relativeProperty.PropertyName);
+                        }
+                    }
+                }
+
+                OnPropertyChangedWithData(property);
+            }
+        }
+
+        private static Dictionary<BindableProperty, HashSet<BindableProperty>> PropertyToGroup { get; }
+            = new Dictionary<BindableProperty, HashSet<BindableProperty>>();
+
+        [Flags]
+        enum BindableContextAttributes
+        {
+            IsManuallySet = 1 << 0,
+            IsBeingSet = 1 << 1,
+            IsDynamicResource = 1 << 2,
+            IsSetFromStyle = 1 << 3,
+            IsDefaultValue = 1 << 4,
+            IsDefaultValueCreated = 1 << 5,
+        }
+
+        class BindablePropertyContext
+        {
+            public BindableContextAttributes Attributes;
+            public BindingBase Binding;
+            public Queue<SetValueArgs> DelayedSetters;
+            public BindableProperty Property;
+            public object Value;
+        }
+
+        [Flags]
+        internal enum SetValuePrivateFlags
+        {
+            None = 0,
+            CheckAccess = 1 << 0,
+            Silent = 1 << 1,
+            ManuallySet = 1 << 2,
+            FromStyle = 1 << 3,
+            Converted = 1 << 4,
+            Default = CheckAccess
+        }
+
+        class SetValueArgs
+        {
+            public readonly SetValueFlags Attributes;
+            public readonly BindablePropertyContext Context;
+            public readonly bool CurrentlyApplying;
+            public readonly BindableProperty Property;
+            public readonly object Value;
+
+            public SetValueArgs(BindableProperty property, BindablePropertyContext context, object value, bool currentlyApplying, SetValueFlags attributes)
+            {
+                Property = property;
+                Context = context;
+                Value = value;
+                CurrentlyApplying = currentlyApplying;
+                Attributes = attributes;
+            }
+        }
+
+        internal void ReplaceBindingElement(Dictionary<string, object> oldNameScope, Dictionary<string, object> newNameScope)
+        {
+            var xElementToNameOfOld = new Dictionary<object, string>();
+
+            foreach (var pair in oldNameScope)
+            {
+                xElementToNameOfOld.Add(pair.Value, pair.Key);
+            }
+
+            foreach (var property in properties)
+            {
+                if (property.Value.Binding is Binding binding && null != binding.Source)
+                {
+                    string xName;
+                    xElementToNameOfOld.TryGetValue(binding.Source, out xName);
+
+                    if (null != xName)
+                    {
+                        var newObject = newNameScope[xName];
+                        binding.Unapply();
+                        binding.Source = newObject;
+                        SetBinding(property.Key, binding);
+                    }
+                }
+            }
+
+            if (null != BindingContext)
+            {
+                string xName;
+                xElementToNameOfOld.TryGetValue(BindingContext, out xName);
+
+                if (null != xName)
+                {
+                    var newObject = newNameScope[xName];
+                    BindingContext = newObject;
+                }
+            }
+        }
+
+        /// <summary>
+        /// Unapplies all previously set bindings.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public void ClearBinding()
+        {
+            foreach (var property in properties)
+            {
+                if (null != property.Value.Binding)
+                {
+                    property.Value.Binding.Unapply();
+                }
+            }
+        }
+    }
 }
 
-namespace Tizen.NUI.Internals
+namespace Tizen.NUI.Binding.Internals
 {
     /// <summary>
     /// SetValueFlags. For internal use.
     /// </summary>
-       [Flags]
-       [EditorBrowsable(EditorBrowsableState.Never)]
-       public enum SetValueFlags
-       {
+    [Flags]
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    public enum SetValueFlags
+    {
         /// <summary>
         /// None.
         /// </summary>
-               None = 0,
+        /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        None = 0,
 
         /// <summary>
         /// Clear OneWay bindings.
         /// </summary>
-               ClearOneWayBindings = 1 << 0,
+        /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        ClearOneWayBindings = 1 << 0,
 
         /// <summary>
         /// Clear TwoWay bindings.
         /// </summary>
-               ClearTwoWayBindings = 1 << 1,
+        /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        ClearTwoWayBindings = 1 << 1,
 
         /// <summary>
         /// Clear dynamic resource.
         /// </summary>
-               ClearDynamicResource = 1 << 2,
+        /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        ClearDynamicResource = 1 << 2,
 
         /// <summary>
         /// Raise or equal.
         /// </summary>
-               RaiseOnEqual = 1 << 3
-       }
-}
\ No newline at end of file
+        /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        RaiseOnEqual = 1 << 3
+    }
+}