From: Fang Xiaohui Date: Wed, 8 Dec 2021 06:40:11 +0000 (+0800) Subject: [NUI] Add API so that user can copy properties, bindings from other container X-Git-Tag: accepted/tizen/unified/20231205.024657~1267 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=720d52652b0acd6c51cf0d70612149f23540e2a6;p=platform%2Fcore%2Fcsapi%2Ftizenfx.git [NUI] Add API so that user can copy properties, bindings from other container --- diff --git a/src/Tizen.NUI/src/public/Common/Container.cs b/src/Tizen.NUI/src/public/Common/Container.cs index 799251c..b173715 100755 --- a/src/Tizen.NUI/src/public/Common/Container.cs +++ b/src/Tizen.NUI/src/public/Common/Container.cs @@ -17,7 +17,9 @@ using System; using System.Collections.Generic; +using System.ComponentModel; using Tizen.NUI.BaseComponents; +using Tizen.NUI.Binding.Internals; namespace Tizen.NUI { @@ -80,6 +82,92 @@ namespace Tizen.NUI } /// + /// Copy all properties, bindings. + /// Copy children without xName from other container, copy all properties, bindings of children with xName. + /// + /// + [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(); + } + } + } + } + + /// /// Adds a child view to this Container. /// ///
This Container (the parent) has been initialized. The child view has been initialized. The child view is not the same as the parent view.
@@ -125,5 +213,69 @@ namespace Tizen.NUI 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(); + + 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(); + + 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 oldNameScope, Dictionary newNameScope) + { + if (IsCreateByXaml) + { + ReplaceBindingElement(oldNameScope, newNameScope); + + foreach (var child in Children) + { + child.ReplaceBindingElementInWholeTree(oldNameScope, newNameScope); + } + } + } } } // namespace Tizen.NUI diff --git a/src/Tizen.NUI/src/public/XamlBinding/BindableObject.cs b/src/Tizen.NUI/src/public/XamlBinding/BindableObject.cs index 6a0a2f8..7b8f413 100755 --- a/src/Tizen.NUI/src/public/XamlBinding/BindableObject.cs +++ b/src/Tizen.NUI/src/public/XamlBinding/BindableObject.cs @@ -20,6 +20,7 @@ using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Reflection; +using System.Linq; using System.Runtime.CompilerServices; using Tizen.NUI.Binding.Internals; @@ -67,7 +68,7 @@ namespace Tizen.NUI.Binding } })); - readonly List properties = new List(4); + readonly Dictionary properties = new Dictionary(4); bool applying; object inheritedContext; @@ -115,7 +116,7 @@ namespace Tizen.NUI.Binding { 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); @@ -129,6 +130,34 @@ namespace Tizen.NUI.Binding } /// + /// Copy all binding from other object. + /// + /// + [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); + } + } + } + + /// /// Raised whenever the BindingContext property changes. /// /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API. @@ -292,6 +321,22 @@ namespace Tizen.NUI.Binding OnPropertyChanged(property.PropertyName); OnPropertyChangedWithData(property); } + + SettedPropeties.Add(property); + } + + private HashSet settedPropeties; + private HashSet SettedPropeties + { + get + { + if (null == settedPropeties) + { + settedPropeties = new HashSet(); + } + + return settedPropeties; + } } internal void SetValueAndForceSendChangeSignal(BindableProperty property, object value) @@ -435,9 +480,8 @@ namespace Tizen.NUI.Binding [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; @@ -464,10 +508,8 @@ namespace Tizen.NUI.Binding { 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; @@ -502,10 +544,8 @@ namespace Tizen.NUI.Binding { 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; @@ -544,9 +584,8 @@ namespace Tizen.NUI.Binding 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; @@ -747,7 +786,7 @@ namespace Tizen.NUI.Binding 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]; @@ -833,24 +872,12 @@ namespace Tizen.NUI.Binding else context.Attributes = BindableContextAttributes.IsDefaultValueCreated; - properties.Add(context); + properties.Add(property, context); return context; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - BindablePropertyContext GetContext(BindableProperty property) - { - List 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) @@ -1076,6 +1103,56 @@ namespace Tizen.NUI.Binding children.Remove(child); } + internal void ReplaceBindingElement(Dictionary oldNameScope, Dictionary newNameScope) + { + var xElementToNameOfOld = new Dictionary(); + + 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 children = new List(); private void FlushBinding() diff --git a/src/Tizen.NUI/src/public/XamlBinding/Internals/NameScope.cs b/src/Tizen.NUI/src/public/XamlBinding/Internals/NameScope.cs index 1823b75..69f9683 100755 --- a/src/Tizen.NUI/src/public/XamlBinding/Internals/NameScope.cs +++ b/src/Tizen.NUI/src/public/XamlBinding/Internals/NameScope.cs @@ -32,7 +32,37 @@ namespace Tizen.NUI.Binding.Internals [EditorBrowsable(EditorBrowsableState.Never)] public static readonly BindableProperty NameScopeProperty = BindableProperty.CreateAttached("NameScope", typeof(INameScope), typeof(NameScope), default(INameScope)); - readonly Dictionary names = new Dictionary(); + private readonly Dictionary names = new Dictionary(); + internal Dictionary NameToElement + { + get + { + return names; + } + } + + internal bool Equal(NameScope other) + { + if (null == other) + { + return false; + } + + if (names.Count != other.names.Count) + { + return false; + } + + foreach (var pair in names) + { + if (!other.names.ContainsKey(pair.Key)) + { + return false; + } + } + + return true; + } object INameScope.FindByName(string name) {