@@ -15,10 +15,10 @@ namespace UnityMvvmToolkit.UITK.BindableUIElements
15
15
public partial class BindableDropdownField : DropdownField , IBindableCollection , IInitializable , IDisposable
16
16
{
17
17
private IProperty < string > _selectedItemProperty ;
18
- private IReadOnlyProperty < ObservableCollection < string > > _itemsSource ;
19
-
20
18
private PropertyBindingData _selectedItemBindingData ;
19
+
21
20
private PropertyBindingData _itemsSourceBindingData ;
21
+ private IReadOnlyProperty < ObservableCollection < string > > _itemsSource ;
22
22
23
23
public void Initialize ( )
24
24
{
@@ -27,102 +27,155 @@ public void Initialize()
27
27
28
28
public void Dispose ( )
29
29
{
30
- choices . Clear ( ) ;
30
+ RemoveAllItems ( ) ;
31
31
}
32
-
32
+
33
33
public void SetBindingContext ( IBindingContext context , IObjectProvider objectProvider )
34
34
{
35
- if ( string . IsNullOrWhiteSpace ( BindingItemsSourcePath ) == false )
35
+ if ( string . IsNullOrWhiteSpace ( BindingItemsSourcePath ) )
36
36
{
37
- _itemsSourceBindingData ??= BindingItemsSourcePath . ToPropertyBindingData ( ) ;
38
- _itemsSource = objectProvider
39
- . RentReadOnlyProperty < ObservableCollection < string > > ( context , _itemsSourceBindingData ) ;
40
- _itemsSource . Value . CollectionChanged += OnItemsCollectionChanged ;
41
- choices = new List < string > ( _itemsSource . Value ) ;
37
+ return ;
42
38
}
43
-
39
+
40
+ _itemsSourceBindingData ??= BindingItemsSourcePath . ToPropertyBindingData ( ) ;
41
+
42
+ _itemsSource =
43
+ objectProvider . RentReadOnlyProperty < ObservableCollection < string > > ( context , _itemsSourceBindingData ) ;
44
+ _itemsSource . Value . CollectionChanged += OnItemsCollectionChanged ;
45
+
46
+ AddItems ( _itemsSource . Value ) ;
47
+
44
48
if ( string . IsNullOrWhiteSpace ( BindingSelectedItemPath ) == false )
45
49
{
46
50
_selectedItemBindingData ??= BindingSelectedItemPath . ToPropertyBindingData ( ) ;
51
+
47
52
_selectedItemProperty = objectProvider . RentProperty < string > ( context , _selectedItemBindingData ) ;
48
- _selectedItemProperty . ValueChanged += OnSelectedItemValueChanged ;
49
-
50
- var isContains = choices . Contains ( _selectedItemProperty . Value ) ;
51
- if ( isContains == true )
53
+
54
+ if ( string . IsNullOrWhiteSpace ( _selectedItemProperty . Value ) )
55
+ {
56
+ _selectedItemProperty . Value = choices . Count > 0 ? choices [ 0 ] : default ;
57
+ }
58
+ else
52
59
{
53
60
UpdateControlValue ( _selectedItemProperty . Value ) ;
54
61
}
55
-
56
- this . RegisterValueChangedCallback ( OnControlValueChanged ) ;
57
- _selectedItemProperty . Value = choices . Count > 0 ? choices [ 0 ] : default ;
62
+
63
+ _selectedItemProperty . ValueChanged += OnSelectedItemValueChanged ;
64
+ this . RegisterValueChangedCallback ( OnControlSelectedValueChanged ) ;
58
65
}
59
66
}
60
67
68
+ public virtual void ResetBindingContext ( IObjectProvider objectProvider )
69
+ {
70
+ if ( _itemsSource is null )
71
+ {
72
+ return ;
73
+ }
74
+
75
+ _itemsSource . Value . CollectionChanged -= OnItemsCollectionChanged ;
76
+ objectProvider . ReturnReadOnlyProperty ( _itemsSource ) ;
77
+ _itemsSource = null ;
78
+
79
+ if ( _selectedItemProperty is not null )
80
+ {
81
+ _selectedItemProperty . ValueChanged -= OnSelectedItemValueChanged ;
82
+ objectProvider . ReturnProperty ( _selectedItemProperty ) ;
83
+ _selectedItemProperty = null ;
84
+
85
+ this . UnregisterValueChangedCallback ( OnControlSelectedValueChanged ) ;
86
+ }
87
+
88
+ RemoveAllItems ( ) ;
89
+ }
90
+
61
91
protected virtual void OnItemsCollectionChanged ( object sender , NotifyCollectionChangedEventArgs e )
62
92
{
63
93
if ( e . Action == NotifyCollectionChangedAction . Add )
64
94
{
65
95
foreach ( string newItem in e . NewItems )
66
96
{
67
- choices . Add ( newItem ) ;
97
+ AddItem ( newItem ) ;
68
98
}
69
99
}
70
100
71
101
if ( e . Action == NotifyCollectionChangedAction . Remove )
72
102
{
73
103
foreach ( string oldItem in e . OldItems )
74
104
{
75
- choices . Remove ( oldItem ) ;
105
+ RemoveItem ( oldItem ) ;
76
106
}
77
107
}
78
-
108
+
79
109
if ( e . Action == NotifyCollectionChangedAction . Reset )
80
110
{
81
- choices . Clear ( ) ;
111
+ if ( _itemsSource . Value . Count == 0 )
112
+ {
113
+ RemoveAllItems ( ) ;
114
+ }
115
+ else
116
+ {
117
+ throw new InvalidOperationException ( "Action not supported." ) ;
118
+ }
82
119
}
83
120
}
84
121
85
- public virtual void ResetBindingContext ( IObjectProvider objectProvider )
122
+ protected virtual void OnControlSelectedValueChanged ( ChangeEvent < string > e )
123
+ {
124
+ _selectedItemProperty . Value = e . newValue ;
125
+ }
126
+
127
+ private void OnSelectedItemValueChanged ( object sender , string newValue )
86
128
{
87
- if ( _selectedItemProperty != null )
129
+ UpdateControlValue ( newValue ) ;
130
+ }
131
+
132
+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
133
+ protected virtual void UpdateControlValue ( string selectedItem )
134
+ {
135
+ if ( choices . Any ( ) && choices . Contains ( selectedItem ) == false )
88
136
{
89
- _selectedItemProperty . ValueChanged -= OnSelectedItemValueChanged ;
90
- objectProvider . ReturnProperty ( _selectedItemProperty ) ;
91
- _selectedItemProperty = null ;
92
- this . UnregisterValueChangedCallback ( OnControlValueChanged ) ;
137
+ throw new InvalidOperationException ( $ "\" { selectedItem } \" is not presented in the collection.") ;
93
138
}
94
-
95
- if ( _itemsSource != null )
139
+
140
+ SetValueWithoutNotify ( selectedItem ) ;
141
+ }
142
+
143
+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
144
+ private void AddItems ( IEnumerable < string > items )
145
+ {
146
+ foreach ( var item in items )
96
147
{
97
- _itemsSource . Value . CollectionChanged -= OnItemsCollectionChanged ;
98
- choices = new List < string > ( ) ;
99
- objectProvider . ReturnReadOnlyProperty ( _itemsSource ) ;
100
- _itemsSource = null ;
148
+ AddItem ( item ) ;
101
149
}
102
-
103
- UpdateControlValue ( default ) ;
104
150
}
105
151
106
- protected virtual void OnControlValueChanged ( ChangeEvent < string > e )
152
+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
153
+ private void AddItem ( string item )
107
154
{
108
- _selectedItemProperty . Value = e . newValue ;
155
+ if ( string . IsNullOrWhiteSpace ( item ) )
156
+ {
157
+ throw new NullReferenceException ( "Item cannot be null or empty." ) ;
158
+ }
159
+
160
+ choices . Add ( item ) ;
109
161
}
110
162
111
- private void OnSelectedItemValueChanged ( object sender , string newValue )
163
+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
164
+ private void RemoveItem ( string item )
112
165
{
113
- var isContains = choices . Contains ( newValue ) ;
114
- if ( isContains == false )
166
+ choices . Remove ( item ) ;
167
+
168
+ if ( value == item )
115
169
{
116
- return ;
170
+ value = choices . Count == 0 ? default : choices [ ^ 1 ] ;
117
171
}
118
-
119
- UpdateControlValue ( newValue ) ;
120
172
}
121
-
173
+
122
174
[ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
123
- protected virtual void UpdateControlValue ( string newValue )
175
+ private void RemoveAllItems ( )
124
176
{
125
- SetValueWithoutNotify ( newValue ) ;
177
+ choices . Clear ( ) ;
178
+ value = default ;
126
179
}
127
180
}
128
181
}
0 commit comments