using System;
using System.Collections.Generic;
+using System.ComponentModel;
using Tizen.NUI.BaseComponents;
+using Tizen.NUI.Binding.Internals;
namespace Tizen.NUI
{
}
/// <summary>
+ /// Copy all properties, bindings.
+ /// Copy children without xName from other container, copy all properties, bindings of children with xName.
+ /// </summary>
+ /// <param name="other"></param>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public void CopyAndKeepXNameInstance(Container other)
+ {
+ CopyFrom(other);
+
+ var nameScopeOfOther = NameScope.GetNameScope(other) as NameScope;
+ var nameScope = NameScope.GetNameScope(this) as NameScope;
+
+ if (null == nameScopeOfOther)
+ {
+ if (null != nameScope)
+ {
+ return;
+ }
+ }
+ else if (!nameScopeOfOther.Equal(nameScope))
+ {
+ return;
+ }
+
+ var xNameToElementsOfOther = nameScopeOfOther.NameToElement;
+ var xNameToElements = nameScope.NameToElement;
+
+ if (null != xNameToElements)
+ {
+ foreach (var pair in xNameToElements)
+ {
+ if (pair.Value is View view)
+ {
+ view.Parent?.Remove(view);
+ }
+ }
+ }
+
+ for (int i = Children.Count - 1; i >= 0; i--)
+ {
+ var child = GetChildAt((uint)i);
+ Remove(child);
+
+ child.DisposeIncludeChildren();
+ }
+
+ CopyChildren(other);
+
+ if (null != xNameToElementsOfOther)
+ {
+ foreach (var pair in xNameToElementsOfOther)
+ {
+ if (pair.Value is View view)
+ {
+ var parent = view.Parent;
+
+ if (null != parent)
+ {
+ if (null != xNameToElements)
+ {
+ var holdedXElements = xNameToElements[pair.Key] as View;
+ holdedXElements.CopyBindingRelationShip(view);
+ holdedXElements.CopyFrom(view);
+
+ parent.ReplaceChild(view, holdedXElements);
+ }
+ }
+ }
+ }
+ }
+
+ ReplaceBindingElementInWholeTree(xNameToElementsOfOther, xNameToElements);
+
+ if (null != xNameToElementsOfOther)
+ {
+ foreach (var pair in xNameToElementsOfOther)
+ {
+ if (pair.Value is View view)
+ {
+ view.Dispose();
+ }
+ }
+ }
+ }
+
+ /// <summary>
/// Adds a child view to this Container.
/// </summary>
/// <pre>This Container (the parent) has been initialized. The child view has been initialized. The child view is not the same as the parent view.</pre>
public abstract UInt32 GetChildCount();
internal abstract View FindCurrentChildById(uint id);
+
+ private void DisposeIncludeChildren()
+ {
+ foreach (var child in Children)
+ {
+ child.DisposeIncludeChildren();
+ }
+
+ if (IsCreateByXaml)
+ {
+ Dispose();
+ ClearBinding();
+ }
+ }
+
+ private void CopyChildren(Container other)
+ {
+ var childrenOfOtherView = new List<View>();
+
+ foreach (var child in other.Children)
+ {
+ childrenOfOtherView.Add(child);
+ }
+
+ foreach (var child in childrenOfOtherView)
+ {
+ Add(child);
+ }
+ }
+
+ private void ReplaceChild(View child, View newChild)
+ {
+ int indexOfView = Children.FindIndex((View v) => { return v == child; });
+
+ var childrenNeedtoReAdd = new Stack<View>();
+
+ for (int i = Children.Count - 1; i > indexOfView; i--)
+ {
+ childrenNeedtoReAdd.Push(Children[i]);
+ Remove(Children[i]);
+ }
+
+ Remove(child);
+
+ childrenNeedtoReAdd.Push(newChild);
+
+ while (0 < childrenNeedtoReAdd.Count)
+ {
+ Add(childrenNeedtoReAdd.Pop());
+ }
+ }
+
+ private void ReplaceBindingElementInWholeTree(Dictionary<string, object> oldNameScope, Dictionary<string, object> newNameScope)
+ {
+ if (IsCreateByXaml)
+ {
+ ReplaceBindingElement(oldNameScope, newNameScope);
+
+ foreach (var child in Children)
+ {
+ child.ReplaceBindingElementInWholeTree(oldNameScope, newNameScope);
+ }
+ }
+ }
}
} // namespace Tizen.NUI
using System.ComponentModel;
using System.Diagnostics;
using System.Reflection;
+using System.Linq;
using System.Runtime.CompilerServices;
using Tizen.NUI.Binding.Internals;
}
}));
- readonly List<BindablePropertyContext> properties = new List<BindablePropertyContext>(4);
+ readonly Dictionary<BindableProperty, BindablePropertyContext> properties = new Dictionary<BindableProperty, BindablePropertyContext>(4);
bool applying;
object inheritedContext;
{
nameToBindableProperty2.TryGetValue(keyValuePair.Key, out var bindableProperty);
- if (null != bindableProperty)
+ if (null != bindableProperty && (SettedPropeties.Contains(bindableProperty) || other.SettedPropeties.Contains(bindableProperty)))
{
object value = other.GetValue(bindableProperty);
}
/// <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>
/// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
OnPropertyChanged(property.PropertyName);
OnPropertyChangedWithData(property);
}
+
+ SettedPropeties.Add(property);
+ }
+
+ private HashSet<BindableProperty> settedPropeties;
+ private HashSet<BindableProperty> SettedPropeties
+ {
+ get
+ {
+ if (null == settedPropeties)
+ {
+ settedPropeties = new HashSet<BindableProperty>();
+ }
+
+ return settedPropeties;
+ }
}
internal void SetValueAndForceSendChangeSignal(BindableProperty property, object value)
[EditorBrowsable(EditorBrowsableState.Never)]
protected void UnapplyBindings()
{
- for (int i = 0, _propertiesCount = properties.Count; i < _propertiesCount; i++)
+ foreach (var context in properties.Values)
{
- BindablePropertyContext context = properties[i];
if (context.Binding == null)
continue;
{
var values = new object[2];
- for (var i = 0; i < properties.Count; i++)
+ foreach (var context in properties.Values)
{
- BindablePropertyContext context = properties[i];
-
if (ReferenceEquals(context.Property, property0))
{
values[0] = context.Value;
{
var values = new object[3];
- for (var i = 0; i < properties.Count; i++)
+ foreach (var context in properties.Values)
{
- BindablePropertyContext context = properties[i];
-
if (ReferenceEquals(context.Property, property0))
{
values[0] = context.Value;
internal object[] GetValues(params BindableProperty[] properties)
{
var values = new object[properties.Length];
- for (var i = 0; i < this.properties.Count; i++)
+ foreach (var context in this.properties.Values)
{
- var context = this.properties[i];
var index = properties.IndexOf(context.Property);
if (index < 0)
continue;
internal void ApplyBindings(bool skipBindingContext, bool fromBindingContextChanged)
{
- var prop = properties.ToArray();
+ var prop = properties.Values.ToArray();
for (int i = 0, propLength = prop.Length; i < propLength; i++)
{
BindablePropertyContext context = prop[i];
else
context.Attributes = BindableContextAttributes.IsDefaultValueCreated;
- properties.Add(context);
+ properties.Add(property, context);
return context;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- BindablePropertyContext GetContext(BindableProperty property)
- {
- List<BindablePropertyContext> propertyList = properties;
-
- for (var i = 0; i < propertyList.Count; i++)
- {
- BindablePropertyContext context = propertyList[i];
- if (ReferenceEquals(context.Property, property))
- return context;
- }
-
- return null;
- }
+ BindablePropertyContext GetContext(BindableProperty property) => properties.TryGetValue(property, out var result) ? result : null;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
BindablePropertyContext GetOrCreateContext(BindableProperty property)
children.Remove(child);
}
+ 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;
+ }
+ }
+ }
+
+ internal void ClearBinding()
+ {
+ foreach (var property in properties)
+ {
+ if (null != property.Value.Binding)
+ {
+ property.Value.Binding.Unapply();
+ }
+ }
+ }
+
private List<BindableObject> children = new List<BindableObject>();
private void FlushBinding()