[NUI] Add attached bindable property CheckBoxGroup.IsGroupHolder to the View. (#3426)
authorJiyun Yang <ji.yang@samsung.com>
Tue, 17 Aug 2021 08:11:27 +0000 (17:11 +0900)
committerdongsug-song <35130733+dongsug-song@users.noreply.github.com>
Wed, 18 Aug 2021 03:10:44 +0000 (12:10 +0900)
In NUI, the parent View that holds checkboxes does not related with CheckBoxGroup.
Which means user must create CheckBoxGroup manually and then add all checkbox to the group.

```
var check1 = new CheckBox();
var check2 = new CheckBox();
var check3 = new CheckBox();

parent.Add(check1);
parent.Add(check2);
parent.Add(check3);

var group = new CheckBoxGroup();
group.Add(check1);
group.Add(check2);
group.Add(check3);
```

In this structure, user can not make a group in XAML code.
This patch introduce attached property to the View for the CheckBoxGroup:
```
<View CheckBoxGroup.IsGroupHolder="True">
  <CheckBox Text="Check1"/>
  <CheckBox Text="Check2"/>
  <CheckBox Text="Check3"/>
</View>
```

And then the user can access check box group from the View using GetCheckBoxGroup(view).

Signed-off-by: Jiyun Yang <ji.yang@samsung.com>
src/Tizen.NUI.Components/Controls/CheckBoxGroup.cs
src/Tizen.NUI.Components/Controls/RadioButtonGroup.cs
src/Tizen.NUI.Components/Controls/SelectGroup.cs

index bf3a9bc..0decb0d 100755 (executable)
  * limitations under the License.
  *
  */
+
+using System;
 using System.ComponentModel;
 using System.Collections.Generic;
+using Tizen.NUI.BaseComponents;
+using Tizen.NUI.Binding;
 
 namespace Tizen.NUI.Components
 {
@@ -34,6 +38,14 @@ namespace Tizen.NUI.Components
     [EditorBrowsable(EditorBrowsableState.Never)]
     public class CheckBoxGroup : SelectGroup
     {
+        /// <summary>
+        /// IsGroupHolderProperty
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static readonly BindableProperty IsGroupHolderProperty = BindableProperty.CreateAttached("IsGroupHolder", typeof(bool), typeof(View), false, propertyChanged: OnIsGroupHolderChanged);
+
+        private static readonly BindableProperty CheckBoxGroupProperty = BindableProperty.CreateAttached("CheckBoxGroup", typeof(CheckBoxGroup), typeof(View), null, propertyChanged: OnCheckBoxGroupChanged);
+
         static CheckBoxGroup() { }
 
         /// <summary>
@@ -47,6 +59,28 @@ namespace Tizen.NUI.Components
         }
 
         /// <summary>
+        /// Gets a CheckBoxGroup.IsGroupHolder property of a view.
+        /// </summary>
+        /// <param name="view">The group holder.</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static bool GetIsGroupHolder(View view) => (bool)view.GetValue(IsGroupHolderProperty);
+
+        /// <summary>
+        /// Sets a CheckBoxGroup.IsGroupHolder property for a view.
+        /// </summary>
+        /// <param name="view">The group holder.</param>
+        /// <param name="value">The value to set.</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static void SetIsGroupHolder(View view, bool value) => view.SetValue(IsGroupHolderProperty, value, false, true);
+
+        /// <summary>
+        /// Gets a attached CheckBoxGroup for a view.
+        /// </summary>
+        /// <param name="view">The group holder.</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static CheckBoxGroup GetCheckBoxGroup(View view) => view.GetValue(CheckBoxGroupProperty) as CheckBoxGroup;
+
+        /// <summary>
         /// Add CheckBox to the end of CheckBoxGroup.
         /// </summary>
         /// <param name="check">The CheckBox to be added to the CheckBoxGroup</param>
@@ -164,5 +198,56 @@ namespace Tizen.NUI.Components
                 cb.IsSelected = state;
             }
         }
+
+        private static void OnIsGroupHolderChanged(Binding.BindableObject bindable, object oldValue, object newValue)
+        {
+            var view = bindable as View;
+
+            if (view == null) return;
+
+            if (!(bool)newValue)
+            {
+                view.SetValue(CheckBoxGroupProperty, null, false, true);
+                return;
+            }
+
+            if (view.GetValue(CheckBoxGroupProperty) == null)
+            {
+                view.SetValue(CheckBoxGroupProperty, new CheckBoxGroup(), false, true);
+            }
+        }
+
+        private static void OnCheckBoxGroupChanged(Binding.BindableObject bindable, object oldValue, object newValue)
+        {
+            var view = bindable as View;
+
+            if (view == null) return;
+
+            if (oldValue is CheckBoxGroup oldGroup)
+            {
+                view.ChildAdded -= oldGroup.OnChildChanged;
+                view.ChildRemoved -= oldGroup.OnChildChanged;
+                oldGroup.RemoveAll();
+            }
+
+            if (newValue is CheckBoxGroup newGroup)
+            {
+                view.ChildAdded += newGroup.OnChildChanged;
+                view.ChildRemoved += newGroup.OnChildChanged;
+                newGroup.OnChildChanged(view, null);
+            }
+        }
+
+        private void OnChildChanged(object sender, EventArgs args)
+        {
+            if (sender is View view)
+            {
+                RemoveAll();
+                foreach (var child in view.Children)
+                {
+                    if (child is CheckBox checkBox) Add(checkBox);
+                }
+            }
+        }
     }
 }
index 4897d57..94c0fe5 100755 (executable)
@@ -179,14 +179,5 @@ namespace Tizen.NUI.Components
                         Add(radioButton);
             }
         }
-
-        private void RemoveAll()
-        {
-            var copied = ItemGroup.ToArray();
-            foreach (var button in copied)
-            {
-                Remove(button as RadioButton);
-            }
-        }
     }
 }
index d022532..b6f4416 100755 (executable)
@@ -168,6 +168,20 @@ namespace Tizen.NUI.Components
             SelectedChanged?.Invoke(this, new EventArgs());
         }
 
+        /// <summary>
+        /// Remove all existing items in the group.
+        /// </summary>
+        private protected void RemoveAll()
+        {
+            foreach (var item in ItemGroup)
+            {
+                item.SelectedChanged -= GroupSelectionHandler;
+                item.ResetItemGroup();
+            }
+
+            ItemGroup.Clear();
+        }
+
         private void GroupSelectionHandler(object sender, SelectedChangedEventArgs args)
         {
             if (isSelectionChanging)