From 173222d5e85d91cb1f1505373866a5050dd303c1 Mon Sep 17 00:00:00 2001 From: Vasilev Date: 2023年6月11日 11:55:53 +0300 Subject: [PATCH 01/11] Written readme for dropdown --- README.md | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/README.md b/README.md index ac16635..1361ef6 100644 --- a/README.md +++ b/README.md @@ -840,6 +840,43 @@ The `BindableButton` can be bound to the following commands: To pass a parameter to the viewmodel, see the [ParameterValueConverter](#parametervalueconverterttargettype) section. +#### BindableDropdownField + +The `BindableDropdownField` allows you to work with dropdown. To set the binding of the selected value, you need to write `binding-selected-value-path`, and to set the binding of all dropdown elements, you need to use `binding-choises-path`. + +The following example demonstrates how to bind to a collection of strings with `BindableDropdownField`. + +In XML, you need to write the following: + +```xml + + + +``` +And in the C# class the following: + +```csharp +public class DropdownFieldViewModel : IBindingContext +{ + public DropdownFieldViewModel() + { + TextValues = new ReadOnlyProperty>(new ObservableCollection() + { + "Value1", + "Value2", + "Value3" + }); + + SelectedValue = new Property(); + SelectedValue.Value = "Value1"; + } + + public IProperty SelectedValue { get; } + + public IReadOnlyProperty> Choices { get; } +} +``` + #### BindableListView The `BindableListView` control is the most efficient way to create lists. It uses virtualization and creates VisualElements only for visible items. Use the `binding-items-source-path` of the `BindableListView` to bind to an `ObservableCollection`. From e3d47f8a54d05f56625310fd9bb3454f1c3ab460 Mon Sep 17 00:00:00 2001 From: Vasilev Date: 2023年6月11日 12:14:09 +0300 Subject: [PATCH 02/11] BindableDropdownField and BindableDropdown TMP --- .../BindableUGUIElements/BindableDropdown.cs | 177 ++++++++++++++++++ .../BindableDropdown.cs.meta | 11 ++ .../BindableDropdownField.cs | 166 ++++++++++++++++ .../BindableDropdownField.cs.meta | 3 + .../Uxmls/BindableDropdownField.Uxml.cs | 60 ++++++ .../Uxmls/BindableDropdownField.Uxml.cs.meta | 3 + 6 files changed, 420 insertions(+) create mode 100644 src/UnityMvvmToolkit.UnityPackage/Assets/Plugins/UnityMvvmToolkit/Runtime/UGUI/BindableUGUIElements/BindableDropdown.cs create mode 100644 src/UnityMvvmToolkit.UnityPackage/Assets/Plugins/UnityMvvmToolkit/Runtime/UGUI/BindableUGUIElements/BindableDropdown.cs.meta create mode 100644 src/UnityMvvmToolkit.UnityPackage/Assets/Plugins/UnityMvvmToolkit/Runtime/UITK/BindableUIElements/BindableDropdownField.cs create mode 100644 src/UnityMvvmToolkit.UnityPackage/Assets/Plugins/UnityMvvmToolkit/Runtime/UITK/BindableUIElements/BindableDropdownField.cs.meta create mode 100644 src/UnityMvvmToolkit.UnityPackage/Assets/Plugins/UnityMvvmToolkit/Runtime/UITK/BindableUIElements/Uxmls/BindableDropdownField.Uxml.cs create mode 100644 src/UnityMvvmToolkit.UnityPackage/Assets/Plugins/UnityMvvmToolkit/Runtime/UITK/BindableUIElements/Uxmls/BindableDropdownField.Uxml.cs.meta diff --git a/src/UnityMvvmToolkit.UnityPackage/Assets/Plugins/UnityMvvmToolkit/Runtime/UGUI/BindableUGUIElements/BindableDropdown.cs b/src/UnityMvvmToolkit.UnityPackage/Assets/Plugins/UnityMvvmToolkit/Runtime/UGUI/BindableUGUIElements/BindableDropdown.cs new file mode 100644 index 0000000..8e527f9 --- /dev/null +++ b/src/UnityMvvmToolkit.UnityPackage/Assets/Plugins/UnityMvvmToolkit/Runtime/UGUI/BindableUGUIElements/BindableDropdown.cs @@ -0,0 +1,177 @@ +#if UNITYMVVMTOOLKIT_TEXTMESHPRO_SUPPORT + +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Collections.Specialized; +using System.Linq; +using System.Runtime.CompilerServices; +using TMPro; +using UnityEngine; +using UnityMvvmToolkit.Core; +using UnityMvvmToolkit.Core.Extensions; +using UnityMvvmToolkit.Core.Interfaces; + +namespace UnityMvvmToolkit.UGUI.BindableUGUIElements +{ + [RequireComponent(typeof(TMP_Dropdown))] + public class BindableDropdown : MonoBehaviour, IBindableElement + { + [SerializeField] private TMP_Dropdown _dropdown; + [SerializeField] private string _bindingValuePath; + [SerializeField] private string _bindingChoicesPath; + + private IProperty _valueProperty; + private IReadOnlyProperty> _itemsSource; + + private PropertyBindingData _propertyBindingData; + private PropertyBindingData _itemsSourceBindingData; + + public void SetBindingContext(IBindingContext context, IObjectProvider objectProvider) + { + if (string.IsNullOrWhiteSpace(_bindingChoicesPath)) + { + return; + } + + _itemsSourceBindingData ??= _bindingChoicesPath.ToPropertyBindingData(); + _propertyBindingData ??= _bindingValuePath.ToPropertyBindingData(); + + _itemsSource = objectProvider + .RentReadOnlyProperty>(context, _itemsSourceBindingData); + _itemsSource.Value.CollectionChanged += OnItemsCollectionChanged; + + _valueProperty = objectProvider.RentProperty(context, _propertyBindingData); + _valueProperty.ValueChanged += OnPropertyValueChanged; + + UpdateControlValue(_dropdown.options.FindIndex(option => option.text == _valueProperty.Value)); + _dropdown.onValueChanged.AddListener(OnControlValueChanged); + + _dropdown.options = new List(_itemsSource.Value.Select(value => new TMP_Dropdown.OptionData(value))); + _valueProperty.Value = _dropdown.options[0].text; + } + + private void OnItemsCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) + { + switch (e.Action) + { + case NotifyCollectionChangedAction.Add: + + if (e.NewItems.Count != 1) + { + throw new NotSupportedException("RangeActionsNotSupported"); + } + + if (e.NewItems?[0] is string newValue) + { + _dropdown.options.Add(new TMP_Dropdown.OptionData(newValue)); + } + break; + + case NotifyCollectionChangedAction.Remove: + + if (e.OldItems.Count != 1) + { + throw new NotSupportedException("RangeActionsNotSupported"); + } + + if (e.OldStartingIndex < 0) + { + throw new InvalidOperationException("RemovedItemNotFound"); + } + + + if (e.OldItems?[0] is string oldValue) + { + _dropdown.options.Remove(new TMP_Dropdown.OptionData(oldValue)); + } + break; + + case NotifyCollectionChangedAction.Replace: + + if (e.NewItems.Count != 1 || e.OldItems.Count != 1) + { + throw new NotSupportedException("RangeActionsNotSupported"); + } + + if (e.NewItems?[0] is string replacingValue && + e.OldItems?[0] is string replacedValue) + { + int indexReplacedValue = _dropdown.options.FindIndex(s => s.text == replacedValue); + + if (indexReplacedValue != -1) + { + _dropdown.options[indexReplacedValue] = new TMP_Dropdown.OptionData(replacingValue); + } + } + break; + + case NotifyCollectionChangedAction.Move: + + if (e.NewItems.Count != 1) + { + throw new NotSupportedException("RangeActionsNotSupported"); + } + if (e.NewStartingIndex < 0) + { + throw new InvalidOperationException("CannotMoveToUnknownPosition"); + } + + if (e.OldItems?[0] is string oldItemMoved) + { + _dropdown.options.Remove(new TMP_Dropdown.OptionData(oldItemMoved)); + _dropdown.options.Insert(e.NewStartingIndex, new TMP_Dropdown.OptionData(oldItemMoved)); + } + break; + + case NotifyCollectionChangedAction.Reset: + _dropdown.options.Clear(); + break; + + default: + { + throw new NotSupportedException("UnexpectedCollectionChangeAction"); + } + } + } + + public virtual void ResetBindingContext(IObjectProvider objectProvider) + { + if (_valueProperty == null || _itemsSource == null) + { + return; + } + + _valueProperty.ValueChanged -= OnPropertyValueChanged; + _itemsSource.Value.CollectionChanged -= OnItemsCollectionChanged; + _dropdown.options = new List(); + + objectProvider.ReturnProperty(_valueProperty); + objectProvider.ReturnReadOnlyProperty(_itemsSource); + + _valueProperty = null; + _itemsSource = null; + + _dropdown.onValueChanged.RemoveListener(OnControlValueChanged); + UpdateControlValue(default); + } + + protected virtual void OnControlValueChanged(int index) + { + _valueProperty.Value = _dropdown.options[index].text; + } + + private void OnPropertyValueChanged(object sender, string newValue) + { + UpdateControlValue(_dropdown.options.FindIndex(option => option.text == newValue)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + protected virtual void UpdateControlValue(int newValue) + { + _dropdown.SetValueWithoutNotify(newValue); + } + } +} + +#endif \ No newline at end of file diff --git a/src/UnityMvvmToolkit.UnityPackage/Assets/Plugins/UnityMvvmToolkit/Runtime/UGUI/BindableUGUIElements/BindableDropdown.cs.meta b/src/UnityMvvmToolkit.UnityPackage/Assets/Plugins/UnityMvvmToolkit/Runtime/UGUI/BindableUGUIElements/BindableDropdown.cs.meta new file mode 100644 index 0000000..05c1cb9 --- /dev/null +++ b/src/UnityMvvmToolkit.UnityPackage/Assets/Plugins/UnityMvvmToolkit/Runtime/UGUI/BindableUGUIElements/BindableDropdown.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f7044586e66117e48948637bf2c66eaa +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/UnityMvvmToolkit.UnityPackage/Assets/Plugins/UnityMvvmToolkit/Runtime/UITK/BindableUIElements/BindableDropdownField.cs b/src/UnityMvvmToolkit.UnityPackage/Assets/Plugins/UnityMvvmToolkit/Runtime/UITK/BindableUIElements/BindableDropdownField.cs new file mode 100644 index 0000000..7424843 --- /dev/null +++ b/src/UnityMvvmToolkit.UnityPackage/Assets/Plugins/UnityMvvmToolkit/Runtime/UITK/BindableUIElements/BindableDropdownField.cs @@ -0,0 +1,166 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Collections.Specialized; +using System.Runtime.CompilerServices; +using UnityEngine.UIElements; +using UnityMvvmToolkit.Core; +using UnityMvvmToolkit.Core.Extensions; +using UnityMvvmToolkit.Core.Interfaces; + +namespace UnityMvvmToolkit.UITK.BindableUIElements +{ + public partial class BindableDropdownField : DropdownField, IBindableElement + { + private IProperty _valueProperty; + private IReadOnlyProperty> _itemsSource; + + private PropertyBindingData _propertyBindingData; + private PropertyBindingData _itemsSourceBindingData; + + public void SetBindingContext(IBindingContext context, IObjectProvider objectProvider) + { + if (string.IsNullOrWhiteSpace(BindingChoicesPath)) + { + return; + } + + _itemsSourceBindingData ??= BindingChoicesPath.ToPropertyBindingData(); + _propertyBindingData ??= BindingValuePath.ToPropertyBindingData(); + + _itemsSource = objectProvider + .RentReadOnlyProperty>(context, _itemsSourceBindingData); + _itemsSource.Value.CollectionChanged += OnItemsCollectionChanged; + + _valueProperty = objectProvider.RentProperty(context, _propertyBindingData); + _valueProperty.ValueChanged += OnPropertyValueChanged; + + UpdateControlValue(_valueProperty.Value); + this.RegisterValueChangedCallback(OnControlValueChanged); + + choices = new List(_itemsSource.Value); + _valueProperty.Value = choices[0]; + } + + private void OnItemsCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) + { + switch (e.Action) + { + case NotifyCollectionChangedAction.Add: + + if (e.NewItems.Count != 1) + { + throw new NotSupportedException("RangeActionsNotSupported"); + } + + if (e.NewItems?[0] is string newValue) + { + choices.Add(newValue); + } + break; + + case NotifyCollectionChangedAction.Remove: + + if (e.OldItems.Count != 1) + { + throw new NotSupportedException("RangeActionsNotSupported"); + } + + if (e.OldStartingIndex < 0) + { + throw new InvalidOperationException("RemovedItemNotFound"); + } + + + if (e.OldItems?[0] is string oldValue) + { + choices.Add(oldValue); + } + break; + + case NotifyCollectionChangedAction.Replace: + + if (e.NewItems.Count != 1 || e.OldItems.Count != 1) + { + throw new NotSupportedException("RangeActionsNotSupported"); + } + + if (e.NewItems?[0] is string replacingValue && + e.OldItems?[0] is string replacedValue) + { + int indexReplacedValue = choices.FindIndex(s => s == replacedValue); + + if (indexReplacedValue != -1) + { + choices[indexReplacedValue] = replacingValue; + } + } + break; + + case NotifyCollectionChangedAction.Move: + + if (e.NewItems.Count != 1) + { + throw new NotSupportedException("RangeActionsNotSupported"); + } + if (e.NewStartingIndex < 0) + { + throw new InvalidOperationException("CannotMoveToUnknownPosition"); + } + + if (e.OldItems?[0] is string oldItemMoved) + { + choices.Remove(oldItemMoved); + choices.Insert(e.NewStartingIndex, oldItemMoved); + } + break; + + case NotifyCollectionChangedAction.Reset: + choices.Clear(); + break; + + default: + { + throw new NotSupportedException("UnexpectedCollectionChangeAction"); + } + } + } + + public virtual void ResetBindingContext(IObjectProvider objectProvider) + { + if (_valueProperty == null || _itemsSource == null) + { + return; + } + + _valueProperty.ValueChanged -= OnPropertyValueChanged; + _itemsSource.Value.CollectionChanged -= OnItemsCollectionChanged; + choices = new List(); + + objectProvider.ReturnProperty(_valueProperty); + objectProvider.ReturnReadOnlyProperty(_itemsSource); + + _valueProperty = null; + _itemsSource = null; + + this.UnregisterValueChangedCallback(OnControlValueChanged); + UpdateControlValue(default); + } + + protected virtual void OnControlValueChanged(ChangeEvent e) + { + _valueProperty.Value = e.newValue; + } + + private void OnPropertyValueChanged(object sender, string newValue) + { + UpdateControlValue(newValue); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + protected virtual void UpdateControlValue(string newValue) + { + SetValueWithoutNotify(newValue); + } + } +} \ No newline at end of file diff --git a/src/UnityMvvmToolkit.UnityPackage/Assets/Plugins/UnityMvvmToolkit/Runtime/UITK/BindableUIElements/BindableDropdownField.cs.meta b/src/UnityMvvmToolkit.UnityPackage/Assets/Plugins/UnityMvvmToolkit/Runtime/UITK/BindableUIElements/BindableDropdownField.cs.meta new file mode 100644 index 0000000..065981e --- /dev/null +++ b/src/UnityMvvmToolkit.UnityPackage/Assets/Plugins/UnityMvvmToolkit/Runtime/UITK/BindableUIElements/BindableDropdownField.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 8c46923c0a364c539ce1f2895dec04ed +timeCreated: 1686411067 \ No newline at end of file diff --git a/src/UnityMvvmToolkit.UnityPackage/Assets/Plugins/UnityMvvmToolkit/Runtime/UITK/BindableUIElements/Uxmls/BindableDropdownField.Uxml.cs b/src/UnityMvvmToolkit.UnityPackage/Assets/Plugins/UnityMvvmToolkit/Runtime/UITK/BindableUIElements/Uxmls/BindableDropdownField.Uxml.cs new file mode 100644 index 0000000..aee9180 --- /dev/null +++ b/src/UnityMvvmToolkit.UnityPackage/Assets/Plugins/UnityMvvmToolkit/Runtime/UITK/BindableUIElements/Uxmls/BindableDropdownField.Uxml.cs @@ -0,0 +1,60 @@ +using UnityEngine.UIElements; +using UnityMvvmToolkit.UITK.Extensions; + +namespace UnityMvvmToolkit.UITK.BindableUIElements +{ + public partial class BindableDropdownField + { + public string BindingValuePath { get; private set; } + + public string BindingChoicesPath { get; private set; } + + + public new class UxmlFactory : UxmlFactory + { + } + +#if UNITY_2023_2_OR_NEWER + [System.Serializable] + public new class UxmlSerializedData : DropdownField.UxmlSerializedData + { + // ReSharper disable once InconsistentNaming + #pragma warning disable 649 + [UnityEngine.SerializeField] private string BindingValuePath; + [UnityEngine.SerializeField] private string BindingItemsSourcePath; + #pragma warning restore 649 + + public override object CreateInstance() => new BindableDropdownField(); + public override void Deserialize(object visualElement) + { + base.Deserialize(visualElement); + visualElement.As().BindingValuePath = BindingValuePath; + visualElement.As().BindingItemsSourcePath = BindingItemsSourcePath; + } + } +#else + public new class UxmlTraits : DropdownField.UxmlTraits + { + private readonly UxmlStringAttributeDescription _bindingValueAttribute = new() + { name = "binding-value-path", defaultValue = "" }; + + private readonly UxmlStringAttributeDescription _bindingChoicesAttribute = new() + { name = "binding-choices-path", defaultValue = "" }; + + public override void Init(VisualElement visualElement, IUxmlAttributes bag, CreationContext context) + { + base.Init(visualElement, bag, context); + + visualElement + .As() + .BindingValuePath = _bindingValueAttribute.GetValueFromBag(bag, context); + + visualElement + .As() + .BindingChoicesPath = _bindingChoicesAttribute.GetValueFromBag(bag, context); + } + } +#endif + + } +} \ No newline at end of file diff --git a/src/UnityMvvmToolkit.UnityPackage/Assets/Plugins/UnityMvvmToolkit/Runtime/UITK/BindableUIElements/Uxmls/BindableDropdownField.Uxml.cs.meta b/src/UnityMvvmToolkit.UnityPackage/Assets/Plugins/UnityMvvmToolkit/Runtime/UITK/BindableUIElements/Uxmls/BindableDropdownField.Uxml.cs.meta new file mode 100644 index 0000000..32d3949 --- /dev/null +++ b/src/UnityMvvmToolkit.UnityPackage/Assets/Plugins/UnityMvvmToolkit/Runtime/UITK/BindableUIElements/Uxmls/BindableDropdownField.Uxml.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 6c58f7387a96411e88df2f3f4963bb93 +timeCreated: 1686411216 \ No newline at end of file From f85cf8666c04ff64e1ced1ef2a3a6a30e7d3cc71 Mon Sep 17 00:00:00 2001 From: Vasilev Date: 2023年6月12日 13:59:16 +0300 Subject: [PATCH 03/11] Cleaunp --- .../BindableDropdownField.cs | 44 ++++++++++++------- .../Uxmls/BindableDropdownField.Uxml.cs | 33 +++++++------- 2 files changed, 43 insertions(+), 34 deletions(-) diff --git a/src/UnityMvvmToolkit.UnityPackage/Assets/Plugins/UnityMvvmToolkit/Runtime/UITK/BindableUIElements/BindableDropdownField.cs b/src/UnityMvvmToolkit.UnityPackage/Assets/Plugins/UnityMvvmToolkit/Runtime/UITK/BindableUIElements/BindableDropdownField.cs index 7424843..eaa636d 100644 --- a/src/UnityMvvmToolkit.UnityPackage/Assets/Plugins/UnityMvvmToolkit/Runtime/UITK/BindableUIElements/BindableDropdownField.cs +++ b/src/UnityMvvmToolkit.UnityPackage/Assets/Plugins/UnityMvvmToolkit/Runtime/UITK/BindableUIElements/BindableDropdownField.cs @@ -4,42 +4,54 @@ using System.Collections.Specialized; using System.Runtime.CompilerServices; using UnityEngine.UIElements; +using UnityMvvmToolkit.Common.Interfaces; using UnityMvvmToolkit.Core; using UnityMvvmToolkit.Core.Extensions; using UnityMvvmToolkit.Core.Interfaces; namespace UnityMvvmToolkit.UITK.BindableUIElements { - public partial class BindableDropdownField : DropdownField, IBindableElement + public partial class BindableDropdownField : DropdownField, IBindableCollection, IInitializable, IDisposable { - private IProperty _valueProperty; + private IProperty _selectedItemProperty; private IReadOnlyProperty> _itemsSource; - private PropertyBindingData _propertyBindingData; + private PropertyBindingData _selectedItemBindingData; private PropertyBindingData _itemsSourceBindingData; + + public void Initialize() + { + choices = new List(); + } + + public void Dispose() + { + choices.Clear(); + } + public void SetBindingContext(IBindingContext context, IObjectProvider objectProvider) { - if (string.IsNullOrWhiteSpace(BindingChoicesPath)) + if (string.IsNullOrWhiteSpace(BindingItemsSourcePath)) { return; } - _itemsSourceBindingData ??= BindingChoicesPath.ToPropertyBindingData(); - _propertyBindingData ??= BindingValuePath.ToPropertyBindingData(); + _itemsSourceBindingData ??= BindingItemsSourcePath.ToPropertyBindingData(); + _selectedItemBindingData ??= BindingSelectedItemPath.ToPropertyBindingData(); _itemsSource = objectProvider .RentReadOnlyProperty>(context, _itemsSourceBindingData); _itemsSource.Value.CollectionChanged += OnItemsCollectionChanged; - _valueProperty = objectProvider.RentProperty(context, _propertyBindingData); - _valueProperty.ValueChanged += OnPropertyValueChanged; + _selectedItemProperty = objectProvider.RentProperty(context, _selectedItemBindingData); + _selectedItemProperty.ValueChanged += OnSelectedItemValueChanged; - UpdateControlValue(_valueProperty.Value); + UpdateControlValue(_selectedItemProperty.Value); this.RegisterValueChangedCallback(OnControlValueChanged); choices = new List(_itemsSource.Value); - _valueProperty.Value = choices[0]; + _selectedItemProperty.Value = choices[0]; } private void OnItemsCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) @@ -128,19 +140,19 @@ private void OnItemsCollectionChanged(object sender, NotifyCollectionChangedEven public virtual void ResetBindingContext(IObjectProvider objectProvider) { - if (_valueProperty == null || _itemsSource == null) + if (_selectedItemProperty == null || _itemsSource == null) { return; } - _valueProperty.ValueChanged -= OnPropertyValueChanged; + _selectedItemProperty.ValueChanged -= OnSelectedItemValueChanged; _itemsSource.Value.CollectionChanged -= OnItemsCollectionChanged; choices = new List(); - objectProvider.ReturnProperty(_valueProperty); + objectProvider.ReturnProperty(_selectedItemProperty); objectProvider.ReturnReadOnlyProperty(_itemsSource); - _valueProperty = null; + _selectedItemProperty = null; _itemsSource = null; this.UnregisterValueChangedCallback(OnControlValueChanged); @@ -149,10 +161,10 @@ public virtual void ResetBindingContext(IObjectProvider objectProvider) protected virtual void OnControlValueChanged(ChangeEvent e) { - _valueProperty.Value = e.newValue; + _selectedItemProperty.Value = e.newValue; } - private void OnPropertyValueChanged(object sender, string newValue) + private void OnSelectedItemValueChanged(object sender, string newValue) { UpdateControlValue(newValue); } diff --git a/src/UnityMvvmToolkit.UnityPackage/Assets/Plugins/UnityMvvmToolkit/Runtime/UITK/BindableUIElements/Uxmls/BindableDropdownField.Uxml.cs b/src/UnityMvvmToolkit.UnityPackage/Assets/Plugins/UnityMvvmToolkit/Runtime/UITK/BindableUIElements/Uxmls/BindableDropdownField.Uxml.cs index aee9180..f89007b 100644 --- a/src/UnityMvvmToolkit.UnityPackage/Assets/Plugins/UnityMvvmToolkit/Runtime/UITK/BindableUIElements/Uxmls/BindableDropdownField.Uxml.cs +++ b/src/UnityMvvmToolkit.UnityPackage/Assets/Plugins/UnityMvvmToolkit/Runtime/UITK/BindableUIElements/Uxmls/BindableDropdownField.Uxml.cs @@ -3,12 +3,11 @@ namespace UnityMvvmToolkit.UITK.BindableUIElements { - public partial class BindableDropdownField + partial class BindableDropdownField { - public string BindingValuePath { get; private set; } - - public string BindingChoicesPath { get; private set; } + public string BindingSelectedItemPath { get; private set; } + public string BindingItemsSourcePath { get; private set; } public new class UxmlFactory : UxmlFactory { @@ -20,7 +19,7 @@ public partial class BindableDropdownField { // ReSharper disable once InconsistentNaming #pragma warning disable 649 - [UnityEngine.SerializeField] private string BindingValuePath; + [UnityEngine.SerializeField] private string BindingSelectedItemPath; [UnityEngine.SerializeField] private string BindingItemsSourcePath; #pragma warning restore 649 @@ -28,33 +27,31 @@ public partial class BindableDropdownField public override void Deserialize(object visualElement) { base.Deserialize(visualElement); - visualElement.As().BindingValuePath = BindingValuePath; - visualElement.As().BindingItemsSourcePath = BindingItemsSourcePath; + + var bindableDropdownField = visualElement.As(); + bindableDropdownField.BindingSelectedItemPath = BindingSelectedItemPath; + bindableDropdownField.BindingItemsSourcePath = BindingItemsSourcePath; } } #else public new class UxmlTraits : DropdownField.UxmlTraits { - private readonly UxmlStringAttributeDescription _bindingValueAttribute = new() - { name = "binding-value-path", defaultValue = "" }; + private readonly UxmlStringAttributeDescription _bindingSelectedItemPath = new() + { name = "binding-selected-item-path", defaultValue = "" }; - private readonly UxmlStringAttributeDescription _bindingChoicesAttribute = new() - { name = "binding-choices-path", defaultValue = "" }; + private readonly UxmlStringAttributeDescription _bindingItemsSourcePath = new() + { name = "binding-items-source-path", defaultValue = "" }; public override void Init(VisualElement visualElement, IUxmlAttributes bag, CreationContext context) { base.Init(visualElement, bag, context); - visualElement - .As() - .BindingValuePath = _bindingValueAttribute.GetValueFromBag(bag, context); + var bindableDropdownField = visualElement.As(); - visualElement - .As() - .BindingChoicesPath = _bindingChoicesAttribute.GetValueFromBag(bag, context); + bindableDropdownField.BindingSelectedItemPath = _bindingSelectedItemPath.GetValueFromBag(bag, context); + bindableDropdownField.BindingItemsSourcePath = _bindingItemsSourcePath.GetValueFromBag(bag, context); } } #endif - } } \ No newline at end of file From 93a5c2bcf4c3826d8bcfdb32bbc07fea844ed991 Mon Sep 17 00:00:00 2001 From: Vasilev Date: 2023年6月12日 14:08:41 +0300 Subject: [PATCH 04/11] Cleanup --- .../BindableUGUIElements/BindableDropdown.cs | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/UnityMvvmToolkit.UnityPackage/Assets/Plugins/UnityMvvmToolkit/Runtime/UGUI/BindableUGUIElements/BindableDropdown.cs b/src/UnityMvvmToolkit.UnityPackage/Assets/Plugins/UnityMvvmToolkit/Runtime/UGUI/BindableUGUIElements/BindableDropdown.cs index 8e527f9..2ae48ec 100644 --- a/src/UnityMvvmToolkit.UnityPackage/Assets/Plugins/UnityMvvmToolkit/Runtime/UGUI/BindableUGUIElements/BindableDropdown.cs +++ b/src/UnityMvvmToolkit.UnityPackage/Assets/Plugins/UnityMvvmToolkit/Runtime/UGUI/BindableUGUIElements/BindableDropdown.cs @@ -18,37 +18,37 @@ namespace UnityMvvmToolkit.UGUI.BindableUGUIElements public class BindableDropdown : MonoBehaviour, IBindableElement { [SerializeField] private TMP_Dropdown _dropdown; - [SerializeField] private string _bindingValuePath; - [SerializeField] private string _bindingChoicesPath; + [SerializeField] private string _bindingSelectedItemPath; + [SerializeField] private string _bindingItemsSourcePath; - private IProperty _valueProperty; + private IProperty _selectedItemProperty; private IReadOnlyProperty> _itemsSource; - private PropertyBindingData _propertyBindingData; + private PropertyBindingData _selectedItemBindingData; private PropertyBindingData _itemsSourceBindingData; public void SetBindingContext(IBindingContext context, IObjectProvider objectProvider) { - if (string.IsNullOrWhiteSpace(_bindingChoicesPath)) + if (string.IsNullOrWhiteSpace(_bindingItemsSourcePath)) { return; } - _itemsSourceBindingData ??= _bindingChoicesPath.ToPropertyBindingData(); - _propertyBindingData ??= _bindingValuePath.ToPropertyBindingData(); + _itemsSourceBindingData ??= _bindingItemsSourcePath.ToPropertyBindingData(); + _selectedItemBindingData ??= _bindingSelectedItemPath.ToPropertyBindingData(); _itemsSource = objectProvider .RentReadOnlyProperty>(context, _itemsSourceBindingData); _itemsSource.Value.CollectionChanged += OnItemsCollectionChanged; - _valueProperty = objectProvider.RentProperty(context, _propertyBindingData); - _valueProperty.ValueChanged += OnPropertyValueChanged; + _selectedItemProperty = objectProvider.RentProperty(context, _selectedItemBindingData); + _selectedItemProperty.ValueChanged += OnPropertySelectedItemChanged; - UpdateControlValue(_dropdown.options.FindIndex(option => option.text == _valueProperty.Value)); + UpdateControlValue(_dropdown.options.FindIndex(option => option.text == _selectedItemProperty.Value)); _dropdown.onValueChanged.AddListener(OnControlValueChanged); _dropdown.options = new List(_itemsSource.Value.Select(value => new TMP_Dropdown.OptionData(value))); - _valueProperty.Value = _dropdown.options[0].text; + _selectedItemProperty.Value = _dropdown.options[0].text; } private void OnItemsCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) @@ -137,19 +137,19 @@ private void OnItemsCollectionChanged(object sender, NotifyCollectionChangedEven public virtual void ResetBindingContext(IObjectProvider objectProvider) { - if (_valueProperty == null || _itemsSource == null) + if (_selectedItemProperty == null || _itemsSource == null) { return; } - _valueProperty.ValueChanged -= OnPropertyValueChanged; + _selectedItemProperty.ValueChanged -= OnPropertySelectedItemChanged; _itemsSource.Value.CollectionChanged -= OnItemsCollectionChanged; _dropdown.options = new List(); - objectProvider.ReturnProperty(_valueProperty); + objectProvider.ReturnProperty(_selectedItemProperty); objectProvider.ReturnReadOnlyProperty(_itemsSource); - _valueProperty = null; + _selectedItemProperty = null; _itemsSource = null; _dropdown.onValueChanged.RemoveListener(OnControlValueChanged); @@ -158,10 +158,10 @@ public virtual void ResetBindingContext(IObjectProvider objectProvider) protected virtual void OnControlValueChanged(int index) { - _valueProperty.Value = _dropdown.options[index].text; + _selectedItemProperty.Value = _dropdown.options[index].text; } - private void OnPropertyValueChanged(object sender, string newValue) + private void OnPropertySelectedItemChanged(object sender, string newValue) { UpdateControlValue(_dropdown.options.FindIndex(option => option.text == newValue)); } From bf6f56455f78267cc4e61cbf4572de3a18c1fe6a Mon Sep 17 00:00:00 2001 From: Vasilev Date: 2023年6月12日 17:23:54 +0300 Subject: [PATCH 05/11] Cleanup --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 1361ef6..248d97f 100644 --- a/README.md +++ b/README.md @@ -842,7 +842,7 @@ To pass a parameter to the viewmodel, see the [ParameterValueConverter](#paramet #### BindableDropdownField -The `BindableDropdownField` allows you to work with dropdown. To set the binding of the selected value, you need to write `binding-selected-value-path`, and to set the binding of all dropdown elements, you need to use `binding-choises-path`. +The `BindableDropdownField` allows you to work with dropdown. To set the binding of the selected value, you need to write `binding-selected-item-path`, and to set the binding of all dropdown elements, you need to use `binding-items-source-path`. The following example demonstrates how to bind to a collection of strings with `BindableDropdownField`. @@ -850,7 +850,7 @@ In XML, you need to write the following: ```xml - + ``` And in the C# class the following: From c2967f8f8adc59999418332392be3a62fdff9564 Mon Sep 17 00:00:00 2001 From: Maxim Vasilev Date: 2023年6月13日 18:36:42 +0300 Subject: [PATCH 06/11] Cleanup --- .../BindableUGUIElements/BindableDropdown.cs | 62 ++++++++++--------- .../BindableDropdownField.cs | 62 ++++++++++--------- 2 files changed, 64 insertions(+), 60 deletions(-) diff --git a/src/UnityMvvmToolkit.UnityPackage/Assets/Plugins/UnityMvvmToolkit/Runtime/UGUI/BindableUGUIElements/BindableDropdown.cs b/src/UnityMvvmToolkit.UnityPackage/Assets/Plugins/UnityMvvmToolkit/Runtime/UGUI/BindableUGUIElements/BindableDropdown.cs index 2ae48ec..450e162 100644 --- a/src/UnityMvvmToolkit.UnityPackage/Assets/Plugins/UnityMvvmToolkit/Runtime/UGUI/BindableUGUIElements/BindableDropdown.cs +++ b/src/UnityMvvmToolkit.UnityPackage/Assets/Plugins/UnityMvvmToolkit/Runtime/UGUI/BindableUGUIElements/BindableDropdown.cs @@ -29,26 +29,24 @@ public class BindableDropdown : MonoBehaviour, IBindableElement public void SetBindingContext(IBindingContext context, IObjectProvider objectProvider) { - if (string.IsNullOrWhiteSpace(_bindingItemsSourcePath)) + if (string.IsNullOrWhiteSpace(_bindingItemsSourcePath) == false) { - return; + _itemsSourceBindingData ??= _bindingItemsSourcePath.ToPropertyBindingData(); + _itemsSource = objectProvider + .RentReadOnlyProperty>(context, _itemsSourceBindingData); + _itemsSource.Value.CollectionChanged += OnItemsCollectionChanged; + _dropdown.options = new List(_itemsSource.Value.Select(value => new TMP_Dropdown.OptionData(value))); } - - _itemsSourceBindingData ??= _bindingItemsSourcePath.ToPropertyBindingData(); - _selectedItemBindingData ??= _bindingSelectedItemPath.ToPropertyBindingData(); - - _itemsSource = objectProvider - .RentReadOnlyProperty>(context, _itemsSourceBindingData); - _itemsSource.Value.CollectionChanged += OnItemsCollectionChanged; - _selectedItemProperty = objectProvider.RentProperty(context, _selectedItemBindingData); - _selectedItemProperty.ValueChanged += OnPropertySelectedItemChanged; - - UpdateControlValue(_dropdown.options.FindIndex(option => option.text == _selectedItemProperty.Value)); - _dropdown.onValueChanged.AddListener(OnControlValueChanged); - - _dropdown.options = new List(_itemsSource.Value.Select(value => new TMP_Dropdown.OptionData(value))); - _selectedItemProperty.Value = _dropdown.options[0].text; + if (string.IsNullOrWhiteSpace(_bindingSelectedItemPath) == false) + { + _selectedItemBindingData ??= _bindingSelectedItemPath.ToPropertyBindingData(); + _selectedItemProperty = objectProvider.RentProperty(context, _selectedItemBindingData); + _selectedItemProperty.ValueChanged += OnPropertySelectedItemChanged; + UpdateControlValue(_dropdown.options.FindIndex(option => option.text == _selectedItemProperty.Value)); + _dropdown.onValueChanged.AddListener(OnControlValueChanged); + _selectedItemProperty.Value = _dropdown.options[0].text; + } } private void OnItemsCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) @@ -137,23 +135,27 @@ private void OnItemsCollectionChanged(object sender, NotifyCollectionChangedEven public virtual void ResetBindingContext(IObjectProvider objectProvider) { - if (_selectedItemProperty == null || _itemsSource == null) + if (_itemsSource != null) { - return; + _itemsSource.Value.CollectionChanged -= OnItemsCollectionChanged; + objectProvider.ReturnReadOnlyProperty(_itemsSource); + _itemsSource = null; + _dropdown.options = new List(); } - - _selectedItemProperty.ValueChanged -= OnPropertySelectedItemChanged; - _itemsSource.Value.CollectionChanged -= OnItemsCollectionChanged; - _dropdown.options = new List(); - - objectProvider.ReturnProperty(_selectedItemProperty); - objectProvider.ReturnReadOnlyProperty(_itemsSource); - _selectedItemProperty = null; - _itemsSource = null; + if (_selectedItemProperty != null) + { + _selectedItemProperty.ValueChanged -= OnPropertySelectedItemChanged; + objectProvider.ReturnProperty(_selectedItemProperty); + _selectedItemProperty = null; + _dropdown.onValueChanged.RemoveListener(OnControlValueChanged); + } - _dropdown.onValueChanged.RemoveListener(OnControlValueChanged); - UpdateControlValue(default); + if (_itemsSource != null + || _selectedItemProperty != null) + { + UpdateControlValue(default); + } } protected virtual void OnControlValueChanged(int index) diff --git a/src/UnityMvvmToolkit.UnityPackage/Assets/Plugins/UnityMvvmToolkit/Runtime/UITK/BindableUIElements/BindableDropdownField.cs b/src/UnityMvvmToolkit.UnityPackage/Assets/Plugins/UnityMvvmToolkit/Runtime/UITK/BindableUIElements/BindableDropdownField.cs index eaa636d..a611cbf 100644 --- a/src/UnityMvvmToolkit.UnityPackage/Assets/Plugins/UnityMvvmToolkit/Runtime/UITK/BindableUIElements/BindableDropdownField.cs +++ b/src/UnityMvvmToolkit.UnityPackage/Assets/Plugins/UnityMvvmToolkit/Runtime/UITK/BindableUIElements/BindableDropdownField.cs @@ -32,26 +32,24 @@ public void Dispose() public void SetBindingContext(IBindingContext context, IObjectProvider objectProvider) { - if (string.IsNullOrWhiteSpace(BindingItemsSourcePath)) + if (string.IsNullOrWhiteSpace(BindingItemsSourcePath) == false) { - return; + _itemsSourceBindingData ??= BindingItemsSourcePath.ToPropertyBindingData(); + _itemsSource = objectProvider + .RentReadOnlyProperty>(context, _itemsSourceBindingData); + _itemsSource.Value.CollectionChanged += OnItemsCollectionChanged; + choices = new List(_itemsSource.Value); } - - _itemsSourceBindingData ??= BindingItemsSourcePath.ToPropertyBindingData(); - _selectedItemBindingData ??= BindingSelectedItemPath.ToPropertyBindingData(); - - _itemsSource = objectProvider - .RentReadOnlyProperty>(context, _itemsSourceBindingData); - _itemsSource.Value.CollectionChanged += OnItemsCollectionChanged; - _selectedItemProperty = objectProvider.RentProperty(context, _selectedItemBindingData); - _selectedItemProperty.ValueChanged += OnSelectedItemValueChanged; - - UpdateControlValue(_selectedItemProperty.Value); - this.RegisterValueChangedCallback(OnControlValueChanged); - - choices = new List(_itemsSource.Value); - _selectedItemProperty.Value = choices[0]; + if (string.IsNullOrWhiteSpace(BindingSelectedItemPath) == false) + { + _selectedItemBindingData ??= BindingSelectedItemPath.ToPropertyBindingData(); + _selectedItemProperty = objectProvider.RentProperty(context, _selectedItemBindingData); + _selectedItemProperty.ValueChanged += OnSelectedItemValueChanged; + UpdateControlValue(_selectedItemProperty.Value); + this.RegisterValueChangedCallback(OnControlValueChanged); + _selectedItemProperty.Value = choices[0]; + } } private void OnItemsCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) @@ -140,23 +138,27 @@ private void OnItemsCollectionChanged(object sender, NotifyCollectionChangedEven public virtual void ResetBindingContext(IObjectProvider objectProvider) { - if (_selectedItemProperty == null || _itemsSource == null) + if (_selectedItemProperty != null) { - return; + _selectedItemProperty.ValueChanged -= OnSelectedItemValueChanged; + objectProvider.ReturnProperty(_selectedItemProperty); + _selectedItemProperty = null; + this.UnregisterValueChangedCallback(OnControlValueChanged); } - - _selectedItemProperty.ValueChanged -= OnSelectedItemValueChanged; - _itemsSource.Value.CollectionChanged -= OnItemsCollectionChanged; - choices = new List(); - - objectProvider.ReturnProperty(_selectedItemProperty); - objectProvider.ReturnReadOnlyProperty(_itemsSource); - _selectedItemProperty = null; - _itemsSource = null; + if (_itemsSource != null) + { + _itemsSource.Value.CollectionChanged -= OnItemsCollectionChanged; + choices = new List(); + objectProvider.ReturnReadOnlyProperty(_itemsSource); + _itemsSource = null; + } - this.UnregisterValueChangedCallback(OnControlValueChanged); - UpdateControlValue(default); + if (_itemsSource != null + || _selectedItemProperty != null) + { + UpdateControlValue(default); + } } protected virtual void OnControlValueChanged(ChangeEvent e) From 1ac27afb6d1c140b10b1fad10898f17fb4d40d37 Mon Sep 17 00:00:00 2001 From: Maxim Vasilev Date: 2023年6月13日 18:38:25 +0300 Subject: [PATCH 07/11] Cleanup --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 248d97f..dad7b2f 100644 --- a/README.md +++ b/README.md @@ -843,6 +843,7 @@ To pass a parameter to the viewmodel, see the [ParameterValueConverter](#paramet #### BindableDropdownField The `BindableDropdownField` allows you to work with dropdown. To set the binding of the selected value, you need to write `binding-selected-item-path`, and to set the binding of all dropdown elements, you need to use `binding-items-source-path`. +Moreover, you can set them independently of each other. The following example demonstrates how to bind to a collection of strings with `BindableDropdownField`. From 8322ae80e4917adc5107e1126cf425fc921feeed Mon Sep 17 00:00:00 2001 From: Maxim Vasilev Date: 2023年6月14日 10:07:59 +0300 Subject: [PATCH 08/11] Cleanup --- .../BindableUGUIElements/BindableDropdown.cs | 31 ++++++------------- .../BindableDropdownField.cs | 30 +++++------------- 2 files changed, 17 insertions(+), 44 deletions(-) diff --git a/src/UnityMvvmToolkit.UnityPackage/Assets/Plugins/UnityMvvmToolkit/Runtime/UGUI/BindableUGUIElements/BindableDropdown.cs b/src/UnityMvvmToolkit.UnityPackage/Assets/Plugins/UnityMvvmToolkit/Runtime/UGUI/BindableUGUIElements/BindableDropdown.cs index 450e162..34106c8 100644 --- a/src/UnityMvvmToolkit.UnityPackage/Assets/Plugins/UnityMvvmToolkit/Runtime/UGUI/BindableUGUIElements/BindableDropdown.cs +++ b/src/UnityMvvmToolkit.UnityPackage/Assets/Plugins/UnityMvvmToolkit/Runtime/UGUI/BindableUGUIElements/BindableDropdown.cs @@ -45,7 +45,7 @@ public void SetBindingContext(IBindingContext context, IObjectProvider objectPro _selectedItemProperty.ValueChanged += OnPropertySelectedItemChanged; UpdateControlValue(_dropdown.options.FindIndex(option => option.text == _selectedItemProperty.Value)); _dropdown.onValueChanged.AddListener(OnControlValueChanged); - _selectedItemProperty.Value = _dropdown.options[0].text; + _selectedItemProperty.Value = _dropdown.options.Count> 0 ? _dropdown.options[0].text : default; } } @@ -55,34 +55,25 @@ private void OnItemsCollectionChanged(object sender, NotifyCollectionChangedEven { case NotifyCollectionChangedAction.Add: - if (e.NewItems.Count != 1) - { - throw new NotSupportedException("RangeActionsNotSupported"); - } - - if (e.NewItems?[0] is string newValue) + foreach (string newItem in e.NewItems) { - _dropdown.options.Add(new TMP_Dropdown.OptionData(newValue)); + _dropdown.options.Add(new TMP_Dropdown.OptionData(newItem)); } + break; case NotifyCollectionChangedAction.Remove: - if (e.OldItems.Count != 1) - { - throw new NotSupportedException("RangeActionsNotSupported"); - } - if (e.OldStartingIndex < 0) { throw new InvalidOperationException("RemovedItemNotFound"); } - - if (e.OldItems?[0] is string oldValue) + foreach (string oldItem in e.OldItems) { - _dropdown.options.Remove(new TMP_Dropdown.OptionData(oldValue)); + _dropdown.options.Remove(new TMP_Dropdown.OptionData(oldItem)); } + break; case NotifyCollectionChangedAction.Replace: @@ -150,12 +141,8 @@ public virtual void ResetBindingContext(IObjectProvider objectProvider) _selectedItemProperty = null; _dropdown.onValueChanged.RemoveListener(OnControlValueChanged); } - - if (_itemsSource != null - || _selectedItemProperty != null) - { - UpdateControlValue(default); - } + + UpdateControlValue(default); } protected virtual void OnControlValueChanged(int index) diff --git a/src/UnityMvvmToolkit.UnityPackage/Assets/Plugins/UnityMvvmToolkit/Runtime/UITK/BindableUIElements/BindableDropdownField.cs b/src/UnityMvvmToolkit.UnityPackage/Assets/Plugins/UnityMvvmToolkit/Runtime/UITK/BindableUIElements/BindableDropdownField.cs index a611cbf..1b92408 100644 --- a/src/UnityMvvmToolkit.UnityPackage/Assets/Plugins/UnityMvvmToolkit/Runtime/UITK/BindableUIElements/BindableDropdownField.cs +++ b/src/UnityMvvmToolkit.UnityPackage/Assets/Plugins/UnityMvvmToolkit/Runtime/UITK/BindableUIElements/BindableDropdownField.cs @@ -18,8 +18,7 @@ public partial class BindableDropdownField : DropdownField, IBindableCollection, private PropertyBindingData _selectedItemBindingData; private PropertyBindingData _itemsSourceBindingData; - - + public void Initialize() { choices = new List(); @@ -48,7 +47,7 @@ public void SetBindingContext(IBindingContext context, IObjectProvider objectPro _selectedItemProperty.ValueChanged += OnSelectedItemValueChanged; UpdateControlValue(_selectedItemProperty.Value); this.RegisterValueChangedCallback(OnControlValueChanged); - _selectedItemProperty.Value = choices[0]; + _selectedItemProperty.Value = choices.Count> 0 ? choices[0] : default; } } @@ -58,34 +57,25 @@ private void OnItemsCollectionChanged(object sender, NotifyCollectionChangedEven { case NotifyCollectionChangedAction.Add: - if (e.NewItems.Count != 1) + foreach (string newItem in e.NewItems) { - throw new NotSupportedException("RangeActionsNotSupported"); + choices.Add(newItem); } - if (e.NewItems?[0] is string newValue) - { - choices.Add(newValue); - } break; case NotifyCollectionChangedAction.Remove: - if (e.OldItems.Count != 1) - { - throw new NotSupportedException("RangeActionsNotSupported"); - } - if (e.OldStartingIndex < 0) { throw new InvalidOperationException("RemovedItemNotFound"); } - - if (e.OldItems?[0] is string oldValue) + foreach (string oldItem in e.OldItems) { - choices.Add(oldValue); + choices.Remove(oldItem); } + break; case NotifyCollectionChangedAction.Replace: @@ -154,11 +144,7 @@ public virtual void ResetBindingContext(IObjectProvider objectProvider) _itemsSource = null; } - if (_itemsSource != null - || _selectedItemProperty != null) - { - UpdateControlValue(default); - } + UpdateControlValue(default); } protected virtual void OnControlValueChanged(ChangeEvent e) From f7806f267bf25a8750d74b820471261a743bb97c Mon Sep 17 00:00:00 2001 From: Maxim Vasilev Date: 2023年6月14日 10:20:00 +0300 Subject: [PATCH 09/11] Cleanup --- .../BindableUGUIElements/BindableDropdown.cs | 16 ++++++++++++++-- .../BindableUIElements/BindableDropdownField.cs | 15 ++++++++++++++- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/src/UnityMvvmToolkit.UnityPackage/Assets/Plugins/UnityMvvmToolkit/Runtime/UGUI/BindableUGUIElements/BindableDropdown.cs b/src/UnityMvvmToolkit.UnityPackage/Assets/Plugins/UnityMvvmToolkit/Runtime/UGUI/BindableUGUIElements/BindableDropdown.cs index 34106c8..4cf93fd 100644 --- a/src/UnityMvvmToolkit.UnityPackage/Assets/Plugins/UnityMvvmToolkit/Runtime/UGUI/BindableUGUIElements/BindableDropdown.cs +++ b/src/UnityMvvmToolkit.UnityPackage/Assets/Plugins/UnityMvvmToolkit/Runtime/UGUI/BindableUGUIElements/BindableDropdown.cs @@ -43,7 +43,13 @@ public void SetBindingContext(IBindingContext context, IObjectProvider objectPro _selectedItemBindingData ??= _bindingSelectedItemPath.ToPropertyBindingData(); _selectedItemProperty = objectProvider.RentProperty(context, _selectedItemBindingData); _selectedItemProperty.ValueChanged += OnPropertySelectedItemChanged; - UpdateControlValue(_dropdown.options.FindIndex(option => option.text == _selectedItemProperty.Value)); + + var foundIndex = _dropdown.options.FindIndex(option => option.text == _selectedItemProperty.Value); + if (foundIndex != -1) + { + UpdateControlValue(foundIndex); + } + _dropdown.onValueChanged.AddListener(OnControlValueChanged); _selectedItemProperty.Value = _dropdown.options.Count> 0 ? _dropdown.options[0].text : default; } @@ -152,7 +158,13 @@ protected virtual void OnControlValueChanged(int index) private void OnPropertySelectedItemChanged(object sender, string newValue) { - UpdateControlValue(_dropdown.options.FindIndex(option => option.text == newValue)); + var foundIndex = _dropdown.options.FindIndex(option => option.text == newValue); + if (foundIndex == -1) + { + return; + } + + UpdateControlValue(foundIndex); } [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/src/UnityMvvmToolkit.UnityPackage/Assets/Plugins/UnityMvvmToolkit/Runtime/UITK/BindableUIElements/BindableDropdownField.cs b/src/UnityMvvmToolkit.UnityPackage/Assets/Plugins/UnityMvvmToolkit/Runtime/UITK/BindableUIElements/BindableDropdownField.cs index 1b92408..c172f3d 100644 --- a/src/UnityMvvmToolkit.UnityPackage/Assets/Plugins/UnityMvvmToolkit/Runtime/UITK/BindableUIElements/BindableDropdownField.cs +++ b/src/UnityMvvmToolkit.UnityPackage/Assets/Plugins/UnityMvvmToolkit/Runtime/UITK/BindableUIElements/BindableDropdownField.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Collections.ObjectModel; using System.Collections.Specialized; +using System.Linq; using System.Runtime.CompilerServices; using UnityEngine.UIElements; using UnityMvvmToolkit.Common.Interfaces; @@ -45,7 +46,13 @@ public void SetBindingContext(IBindingContext context, IObjectProvider objectPro _selectedItemBindingData ??= BindingSelectedItemPath.ToPropertyBindingData(); _selectedItemProperty = objectProvider.RentProperty(context, _selectedItemBindingData); _selectedItemProperty.ValueChanged += OnSelectedItemValueChanged; - UpdateControlValue(_selectedItemProperty.Value); + + var isContains = choices.Contains(_selectedItemProperty.Value); + if (isContains == true) + { + UpdateControlValue(_selectedItemProperty.Value); + } + this.RegisterValueChangedCallback(OnControlValueChanged); _selectedItemProperty.Value = choices.Count> 0 ? choices[0] : default; } @@ -154,6 +161,12 @@ protected virtual void OnControlValueChanged(ChangeEvent e) private void OnSelectedItemValueChanged(object sender, string newValue) { + var isContains = choices.Contains(newValue); + if (isContains == false) + { + return; + } + UpdateControlValue(newValue); } From d0237e75d323a325ee55403cbb371fdd56c63340 Mon Sep 17 00:00:00 2001 From: Maxim Vasilev Date: 2023年6月15日 10:45:18 +0300 Subject: [PATCH 10/11] Changed NotifyCollectionChangedEventArgs --- .../BindableUGUIElements/BindableDropdown.cs | 76 +++--------------- .../BindableDropdownField.cs | 78 +++---------------- 2 files changed, 21 insertions(+), 133 deletions(-) diff --git a/src/UnityMvvmToolkit.UnityPackage/Assets/Plugins/UnityMvvmToolkit/Runtime/UGUI/BindableUGUIElements/BindableDropdown.cs b/src/UnityMvvmToolkit.UnityPackage/Assets/Plugins/UnityMvvmToolkit/Runtime/UGUI/BindableUGUIElements/BindableDropdown.cs index 4cf93fd..932fb61 100644 --- a/src/UnityMvvmToolkit.UnityPackage/Assets/Plugins/UnityMvvmToolkit/Runtime/UGUI/BindableUGUIElements/BindableDropdown.cs +++ b/src/UnityMvvmToolkit.UnityPackage/Assets/Plugins/UnityMvvmToolkit/Runtime/UGUI/BindableUGUIElements/BindableDropdown.cs @@ -57,75 +57,19 @@ public void SetBindingContext(IBindingContext context, IObjectProvider objectPro private void OnItemsCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) { - switch (e.Action) + if (e.Action == NotifyCollectionChangedAction.Add) { - case NotifyCollectionChangedAction.Add: - - foreach (string newItem in e.NewItems) - { - _dropdown.options.Add(new TMP_Dropdown.OptionData(newItem)); - } - - break; - - case NotifyCollectionChangedAction.Remove: - - if (e.OldStartingIndex < 0) - { - throw new InvalidOperationException("RemovedItemNotFound"); - } - - foreach (string oldItem in e.OldItems) - { - _dropdown.options.Remove(new TMP_Dropdown.OptionData(oldItem)); - } - - break; - - case NotifyCollectionChangedAction.Replace: - - if (e.NewItems.Count != 1 || e.OldItems.Count != 1) - { - throw new NotSupportedException("RangeActionsNotSupported"); - } - - if (e.NewItems?[0] is string replacingValue && - e.OldItems?[0] is string replacedValue) - { - int indexReplacedValue = _dropdown.options.FindIndex(s => s.text == replacedValue); + foreach (string newItem in e.NewItems) + { + _dropdown.options.Add(new TMP_Dropdown.OptionData(newItem)); + } + } - if (indexReplacedValue != -1) - { - _dropdown.options[indexReplacedValue] = new TMP_Dropdown.OptionData(replacingValue); - } - } - break; - - case NotifyCollectionChangedAction.Move: - - if (e.NewItems.Count != 1) - { - throw new NotSupportedException("RangeActionsNotSupported"); - } - if (e.NewStartingIndex < 0) - { - throw new InvalidOperationException("CannotMoveToUnknownPosition"); - } - - if (e.OldItems?[0] is string oldItemMoved) - { - _dropdown.options.Remove(new TMP_Dropdown.OptionData(oldItemMoved)); - _dropdown.options.Insert(e.NewStartingIndex, new TMP_Dropdown.OptionData(oldItemMoved)); - } - break; - - case NotifyCollectionChangedAction.Reset: - _dropdown.options.Clear(); - break; - - default: + if (e.Action == NotifyCollectionChangedAction.Remove) + { + foreach (string oldItem in e.OldItems) { - throw new NotSupportedException("UnexpectedCollectionChangeAction"); + _dropdown.options.Remove(new TMP_Dropdown.OptionData(oldItem)); } } } diff --git a/src/UnityMvvmToolkit.UnityPackage/Assets/Plugins/UnityMvvmToolkit/Runtime/UITK/BindableUIElements/BindableDropdownField.cs b/src/UnityMvvmToolkit.UnityPackage/Assets/Plugins/UnityMvvmToolkit/Runtime/UITK/BindableUIElements/BindableDropdownField.cs index c172f3d..5cf78dc 100644 --- a/src/UnityMvvmToolkit.UnityPackage/Assets/Plugins/UnityMvvmToolkit/Runtime/UITK/BindableUIElements/BindableDropdownField.cs +++ b/src/UnityMvvmToolkit.UnityPackage/Assets/Plugins/UnityMvvmToolkit/Runtime/UITK/BindableUIElements/BindableDropdownField.cs @@ -58,77 +58,21 @@ public void SetBindingContext(IBindingContext context, IObjectProvider objectPro } } - private void OnItemsCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) + protected virtual void OnItemsCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) { - switch (e.Action) + if (e.Action == NotifyCollectionChangedAction.Add) { - case NotifyCollectionChangedAction.Add: - - foreach (string newItem in e.NewItems) - { - choices.Add(newItem); - } - - break; - - case NotifyCollectionChangedAction.Remove: - - if (e.OldStartingIndex < 0) - { - throw new InvalidOperationException("RemovedItemNotFound"); - } - - foreach (string oldItem in e.OldItems) - { - choices.Remove(oldItem); - } - - break; - - case NotifyCollectionChangedAction.Replace: - - if (e.NewItems.Count != 1 || e.OldItems.Count != 1) - { - throw new NotSupportedException("RangeActionsNotSupported"); - } - - if (e.NewItems?[0] is string replacingValue && - e.OldItems?[0] is string replacedValue) - { - int indexReplacedValue = choices.FindIndex(s => s == replacedValue); + foreach (string newItem in e.NewItems) + { + choices.Add(newItem); + } + } - if (indexReplacedValue != -1) - { - choices[indexReplacedValue] = replacingValue; - } - } - break; - - case NotifyCollectionChangedAction.Move: - - if (e.NewItems.Count != 1) - { - throw new NotSupportedException("RangeActionsNotSupported"); - } - if (e.NewStartingIndex < 0) - { - throw new InvalidOperationException("CannotMoveToUnknownPosition"); - } - - if (e.OldItems?[0] is string oldItemMoved) - { - choices.Remove(oldItemMoved); - choices.Insert(e.NewStartingIndex, oldItemMoved); - } - break; - - case NotifyCollectionChangedAction.Reset: - choices.Clear(); - break; - - default: + if (e.Action == NotifyCollectionChangedAction.Remove) + { + foreach (string oldItem in e.OldItems) { - throw new NotSupportedException("UnexpectedCollectionChangeAction"); + choices.Remove(oldItem); } } } From 208cd20e0523588586d3f2741f3143546f2189ad Mon Sep 17 00:00:00 2001 From: Vasilev Date: 2023年6月25日 20:13:24 +0300 Subject: [PATCH 11/11] Add Reset --- .../Runtime/UGUI/BindableUGUIElements/BindableDropdown.cs | 5 +++++ .../UITK/BindableUIElements/BindableDropdownField.cs | 7 ++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/UnityMvvmToolkit.UnityPackage/Assets/Plugins/UnityMvvmToolkit/Runtime/UGUI/BindableUGUIElements/BindableDropdown.cs b/src/UnityMvvmToolkit.UnityPackage/Assets/Plugins/UnityMvvmToolkit/Runtime/UGUI/BindableUGUIElements/BindableDropdown.cs index 932fb61..3f0da78 100644 --- a/src/UnityMvvmToolkit.UnityPackage/Assets/Plugins/UnityMvvmToolkit/Runtime/UGUI/BindableUGUIElements/BindableDropdown.cs +++ b/src/UnityMvvmToolkit.UnityPackage/Assets/Plugins/UnityMvvmToolkit/Runtime/UGUI/BindableUGUIElements/BindableDropdown.cs @@ -72,6 +72,11 @@ private void OnItemsCollectionChanged(object sender, NotifyCollectionChangedEven _dropdown.options.Remove(new TMP_Dropdown.OptionData(oldItem)); } } + + if (e.Action == NotifyCollectionChangedAction.Reset) + { + _dropdown.options.Clear(); + } } public virtual void ResetBindingContext(IObjectProvider objectProvider) diff --git a/src/UnityMvvmToolkit.UnityPackage/Assets/Plugins/UnityMvvmToolkit/Runtime/UITK/BindableUIElements/BindableDropdownField.cs b/src/UnityMvvmToolkit.UnityPackage/Assets/Plugins/UnityMvvmToolkit/Runtime/UITK/BindableUIElements/BindableDropdownField.cs index 5cf78dc..cb05421 100644 --- a/src/UnityMvvmToolkit.UnityPackage/Assets/Plugins/UnityMvvmToolkit/Runtime/UITK/BindableUIElements/BindableDropdownField.cs +++ b/src/UnityMvvmToolkit.UnityPackage/Assets/Plugins/UnityMvvmToolkit/Runtime/UITK/BindableUIElements/BindableDropdownField.cs @@ -75,8 +75,13 @@ protected virtual void OnItemsCollectionChanged(object sender, NotifyCollectionC choices.Remove(oldItem); } } + + if (e.Action == NotifyCollectionChangedAction.Reset) + { + choices.Clear(); + } } - + public virtual void ResetBindingContext(IObjectProvider objectProvider) { if (_selectedItemProperty != null)

AltStyle によって変換されたページ (->オリジナル) /