From 0f8b73a6369635f694fa09589e25ba8cdf0ae57b Mon Sep 17 00:00:00 2001 From: Jiyun Yang Date: Tue, 29 Jun 2021 14:33:11 +0900 Subject: [PATCH] [NUI] Add SelectedChanged event to the SelectGroup and etc. (#3221) * Fix default SelectGroup.SelectedIndex value to -1. * Add event SelectGroup.SelectedChanged. * Add method SelectGroup.AddAllToView(). * Add method RadioButtonGroup.GetSelectedItem(). * Add attached property RadioButtonGroup.IsGroupHolder. View can make a RadioButtonGroup for its radio button children. ```xaml ``` Signed-off-by: Jiyun Yang --- .../Controls/RadioButtonGroup.cs | 103 +++++++++++++++++++++ src/Tizen.NUI.Components/Controls/SelectButton.cs | 5 + src/Tizen.NUI.Components/Controls/SelectGroup.cs | 71 ++++++++------ .../src/public/XamlBinding/BindableObject.cs | 2 +- 4 files changed, 153 insertions(+), 28 deletions(-) diff --git a/src/Tizen.NUI.Components/Controls/RadioButtonGroup.cs b/src/Tizen.NUI.Components/Controls/RadioButtonGroup.cs index a028465..4897d57 100755 --- a/src/Tizen.NUI.Components/Controls/RadioButtonGroup.cs +++ b/src/Tizen.NUI.Components/Controls/RadioButtonGroup.cs @@ -14,7 +14,11 @@ * limitations under the License. * */ + +using System; using System.ComponentModel; +using Tizen.NUI.BaseComponents; +using Tizen.NUI.Binding; namespace Tizen.NUI.Components { @@ -35,6 +39,14 @@ namespace Tizen.NUI.Components public class RadioButtonGroup : SelectGroup { /// + /// IsGroupHolderProperty + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static readonly BindableProperty IsGroupHolderProperty = BindableProperty.CreateAttached("IsGroupHolder", typeof(bool), typeof(View), false, propertyChanged: OnIsGroupHolderChanged); + + private static readonly BindableProperty RadioButtonGroupProperty = BindableProperty.CreateAttached("RadioButtonGroup", typeof(RadioButtonGroup), typeof(View), null, propertyChanged: OnRadioButtonGroupChanged); + + /// /// Construct RadioButtonGroup /// /// 6 @@ -46,6 +58,28 @@ namespace Tizen.NUI.Components } /// + /// Gets a RadioButtonGroup.IsGroupHolder property of a view. + /// + /// The group holder. + [EditorBrowsable(EditorBrowsableState.Never)] + public static bool GetIsGroupHolder(View view) => (bool)view.GetValue(IsGroupHolderProperty); + + /// + /// Sets a RadioButtonGroup.IsGroupHolder property for a view. + /// + /// The group holder. + /// The value to set. + [EditorBrowsable(EditorBrowsableState.Never)] + public static void SetIsGroupHolder(View view, bool value) => view.SetValue(IsGroupHolderProperty, value, false, true); + + /// + /// Gets a attached RadioButtonGroup for a view. + /// + /// The group holder. + [EditorBrowsable(EditorBrowsableState.Never)] + public static RadioButtonGroup GetRadioButtonGroup(View view) => view.GetValue(RadioButtonGroupProperty) as RadioButtonGroup; + + /// /// Get the RadioButton object at the specified index. /// /// item index @@ -59,6 +93,16 @@ namespace Tizen.NUI.Components } /// + /// Get the RadioButton object at the currently selected. If no item selected, returns null. + /// + /// Currently selected radio button + [EditorBrowsable(EditorBrowsableState.Never)] + public RadioButton GetSelectedItem() + { + return (SelectedIndex >= 0 && SelectedIndex < ItemGroup.Count) ? ItemGroup[SelectedIndex] as RadioButton : null; + } + + /// /// Add RadioButton to the end of RadioButtonGroup. /// /// The RadioButton to be added to the RadioButtonGroup @@ -85,5 +129,64 @@ namespace Tizen.NUI.Components base.RemoveSelection(radio); radio.ItemGroup = null; } + + 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(RadioButtonGroupProperty, null, false, true); + return; + } + + if (view.GetValue(RadioButtonGroupProperty) == null) + { + view.SetValue(RadioButtonGroupProperty, new RadioButtonGroup(), false, true); + } + } + + private static void OnRadioButtonGroupChanged(Binding.BindableObject bindable, object oldValue, object newValue) + { + var view = bindable as View; + + if (view == null) return; + + if (oldValue is RadioButtonGroup oldGroup) + { + view.ChildAdded -= oldGroup.OnChildChanged; + view.ChildRemoved -= oldGroup.OnChildChanged; + oldGroup.RemoveAll(); + } + + if (newValue is RadioButtonGroup 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 RadioButton radioButton) + Add(radioButton); + } + } + + private void RemoveAll() + { + var copied = ItemGroup.ToArray(); + foreach (var button in copied) + { + Remove(button as RadioButton); + } + } } } diff --git a/src/Tizen.NUI.Components/Controls/SelectButton.cs b/src/Tizen.NUI.Components/Controls/SelectButton.cs index 5d0ba7d..8a62bc4 100755 --- a/src/Tizen.NUI.Components/Controls/SelectButton.cs +++ b/src/Tizen.NUI.Components/Controls/SelectButton.cs @@ -126,6 +126,7 @@ namespace Tizen.NUI.Components if (type == DisposeTypes.Explicit) { + RemoveFromGroup(); } base.Dispose(type); @@ -234,5 +235,9 @@ namespace Tizen.NUI.Components } } } + + internal void RemoveFromGroup() => itemGroup?.RemoveSelection(this); + + internal void ResetItemGroup() => itemGroup = null; } } diff --git a/src/Tizen.NUI.Components/Controls/SelectGroup.cs b/src/Tizen.NUI.Components/Controls/SelectGroup.cs index 01c638d..d022532 100755 --- a/src/Tizen.NUI.Components/Controls/SelectGroup.cs +++ b/src/Tizen.NUI.Components/Controls/SelectGroup.cs @@ -1,5 +1,5 @@ /* - * Copyright(c) 2019 Samsung Electronics Co., Ltd. + * Copyright(c) 2019-2021 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. @@ -17,23 +17,11 @@ using System; using System.Collections.Generic; using System.ComponentModel; +using Tizen.NUI.BaseComponents; namespace Tizen.NUI.Components { /// - /// Selection group event arguments - /// - /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API. - [EditorBrowsable(EditorBrowsableState.Never)] - public class GroupSelectedChangedEventArgs : EventArgs - { - /// The index of selected item - /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API. - [EditorBrowsable(EditorBrowsableState.Never)] - public int SelectedIndex { get; set; } - } - - /// /// SelectionGroup is the base class of CheckBoxGroup and RadioButtonGroup. /// It defines a group that is set of selections and enables the user to choose one or multiple selection. /// @@ -51,7 +39,14 @@ namespace Tizen.NUI.Components [EditorBrowsable(EditorBrowsableState.Never)] protected List ItemGroup { get; } - private int selectedIndex; + private int selectedIndex = -1; + private bool isSelectionChanging = false; + + /// + /// An event for the item selected changed. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public event EventHandler SelectedChanged; /// /// Get the number of items in the SelectionGroup. @@ -63,6 +58,7 @@ namespace Tizen.NUI.Components /// /// Get the index of currently or latest selected item. + /// If no item is selected, returns -1. /// /// 6 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API. @@ -113,21 +109,35 @@ namespace Tizen.NUI.Components } /// + /// Adds all existing items in the group to the View. + /// + /// The target view. + [EditorBrowsable(EditorBrowsableState.Never)] + public void AddAllToView(View target) + { + if (target == null) throw new global::System.ArgumentNullException(nameof(target)); + + foreach (SelectButton button in ItemGroup) target.Add(button); + } + + /// /// Adds an selection to the end of the SelectionGroup /// /// The selection to be added to the end of the SelectionGroup /// 6 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API. [EditorBrowsable(EditorBrowsableState.Never)] - protected void AddSelection(SelectButton selection) + protected internal void AddSelection(SelectButton selection) { if (null == selection) return; if (ItemGroup.Contains(selection)) { return; } + + selection.RemoveFromGroup(); ItemGroup.Add(selection); - selection.SelectedChanged += OnSelectedChanged; + selection.SelectedChanged += GroupSelectionHandler; } /// @@ -137,32 +147,38 @@ namespace Tizen.NUI.Components /// 6 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API. [EditorBrowsable(EditorBrowsableState.Never)] - protected void RemoveSelection(SelectButton selection) + protected internal void RemoveSelection(SelectButton selection) { if (!ItemGroup.Contains(selection)) { return; } - selection.SelectedChanged -= OnSelectedChanged; + selection.SelectedChanged -= GroupSelectionHandler; ItemGroup.Remove(selection); + selection.ResetItemGroup(); } /// /// Called when the state of Selected is changed. /// /// The selection selected by user - /// 6 - /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API. [EditorBrowsable(EditorBrowsableState.Never)] - protected virtual void SelectionHandler(SelectButton selection) + protected virtual void OnSelectedChanged(SelectButton selection) { + SelectedChanged?.Invoke(this, new EventArgs()); } - private void OnSelectedChanged(object sender, SelectedChangedEventArgs args) + private void GroupSelectionHandler(object sender, SelectedChangedEventArgs args) { - SelectButton selection = sender as SelectButton; - if (selection != null) + if (isSelectionChanging) { + return; + } + + if (sender is SelectButton selection) + { + isSelectionChanging = true; + if (args.IsSelected == true) { selectedIndex = selection.Index; @@ -177,9 +193,10 @@ namespace Tizen.NUI.Components } } } - - SelectionHandler(selection); } + + isSelectionChanging = false; + OnSelectedChanged(selection); } } } diff --git a/src/Tizen.NUI/src/public/XamlBinding/BindableObject.cs b/src/Tizen.NUI/src/public/XamlBinding/BindableObject.cs index cadc3af..714e5ed 100755 --- a/src/Tizen.NUI/src/public/XamlBinding/BindableObject.cs +++ b/src/Tizen.NUI/src/public/XamlBinding/BindableObject.cs @@ -845,7 +845,7 @@ namespace Tizen.NUI.Binding context.Binding = null; } - void SetValue(BindableProperty property, object value, bool fromStyle, bool checkAccess) + internal void SetValue(BindableProperty property, object value, bool fromStyle, bool checkAccess) { if (property == null) throw new ArgumentNullException(nameof(property)); -- 2.7.4