11using System ;
22using System . Collections ;
33using System . Collections . Generic ;
4+ using System . Linq ;
45using System . Runtime . CompilerServices ;
56using Plugin . MaterialDesignControls . Animations ;
67using Xamarin . Forms ;
@@ -50,6 +51,24 @@ public Thickness ChipsPadding
5051 set { SetValue ( ChipsPaddingProperty , value ) ; }
5152 }
5253
54+ public static readonly BindableProperty ChipsMarginProperty =
55+ BindableProperty . Create ( nameof ( ChipsMargin ) , typeof ( Thickness ) , typeof ( MaterialChipsGroup ) , defaultValue : new Thickness ( 6 ) ) ;
56+
57+ public Thickness ChipsMargin
58+ {
59+ get { return ( Thickness ) GetValue ( ChipsMarginProperty ) ; }
60+ set { SetValue ( ChipsMarginProperty , value ) ; }
61+ }
62+
63+ public static readonly BindableProperty ChipsFlexLayoutBasisPercentageProperty =
64+ BindableProperty . Create ( nameof ( ChipsFlexLayoutPercentageBasis ) , typeof ( double ) , typeof ( MaterialChipsGroup ) , defaultValue : 0.0 ) ;
65+
66+ public double ChipsFlexLayoutPercentageBasis
67+ {
68+ get { return ( double ) GetValue ( ChipsFlexLayoutBasisPercentageProperty ) ; }
69+ set { SetValue ( ChipsFlexLayoutBasisPercentageProperty , value ) ; }
70+ }
71+
5372 public static readonly new BindableProperty IsEnabledProperty =
5473 BindableProperty . Create ( nameof ( IsEnabled ) , typeof ( bool ) , typeof ( MaterialChipsGroup ) , defaultValue : true ) ;
5574
@@ -69,11 +88,11 @@ public string LabelText
6988 }
7089
7190 public static readonly BindableProperty ItemsSourceProperty =
72- BindableProperty . Create ( nameof ( ItemsSource ) , typeof ( IEnumerable ) , typeof ( MaterialChipsGroup ) , defaultValue : null , propertyChanged : OnItemsSourceChanged ) ;
91+ BindableProperty . Create ( nameof ( ItemsSource ) , typeof ( IEnumerable < string > ) , typeof ( MaterialChipsGroup ) , defaultValue : null , propertyChanged : OnItemsSourceChanged ) ;
7392
74- public IEnumerable ItemsSource
93+ public IEnumerable < string > ItemsSource
7594 {
76- get { return ( IEnumerable ) GetValue ( ItemsSourceProperty ) ; }
95+ get { return ( IEnumerable < string > ) GetValue ( ItemsSourceProperty ) ; }
7796 set { SetValue ( ItemsSourceProperty , value ) ; }
7897 }
7998
@@ -86,6 +105,15 @@ public string SelectedItem
86105 set { SetValue ( SelectedItemProperty , value ) ; }
87106 }
88107
108+ public static readonly BindableProperty SelectedItemsProperty =
109+ BindableProperty . Create ( nameof ( SelectedItems ) , typeof ( List < string > ) , typeof ( MaterialChipsGroup ) , defaultValue : null , propertyChanged : OnSelectedItemsChanged , defaultBindingMode : BindingMode . TwoWay ) ;
110+
111+ public List < string > SelectedItems
112+ {
113+ get { return ( List < string > ) GetValue ( SelectedItemsProperty ) ; }
114+ set { SetValue ( SelectedItemsProperty , value ) ; }
115+ }
116+
89117 public static readonly BindableProperty AssistiveTextProperty =
90118 BindableProperty . Create ( nameof ( AssistiveText ) , typeof ( string ) , typeof ( MaterialChipsGroup ) , defaultValue : null ) ;
91119
@@ -239,33 +267,57 @@ public bool AnimateError
239267 set { SetValue ( AnimateErrorProperty , value ) ; }
240268 }
241269
270+ public static readonly BindableProperty IsMultipleSelectionProperty =
271+ BindableProperty . Create ( nameof ( IsMultipleSelection ) , typeof ( bool ) , typeof ( MaterialChipsGroup ) , defaultValue : false ) ;
272+
273+ public bool IsMultipleSelection
274+ {
275+ get { return ( bool ) GetValue ( IsMultipleSelectionProperty ) ; }
276+ set { SetValue ( IsMultipleSelectionProperty , value ) ; }
277+ }
278+
242279 #endregion Properties
243280
244281 #region Methods
245282
283+ // Single selection
246284 private static void OnSelectedItemChanged ( BindableObject bindable , object oldValue , object newValue )
247285 {
248286 var control = ( MaterialChipsGroup ) bindable ;
249- if ( control . stcContainer . Children != null )
287+ if ( control . flexContainer . Children != null && control . SelectedItem != null )
250288 {
251- foreach ( var item in control . stcContainer . Children )
289+ foreach ( var item in control . flexContainer . Children )
252290 {
253291 if ( item != null && item is MaterialChips )
254- {
255292 ( ( MaterialChips ) item ) . IsSelected = ( ( MaterialChips ) item ) . Text . Equals ( control . SelectedItem ) ;
256- }
293+ }
294+ }
295+ }
296+
297+ // Multiple selection
298+ private static void OnSelectedItemsChanged ( BindableObject bindable , object oldValue , object newValue )
299+ {
300+ var control = ( MaterialChipsGroup ) bindable ;
301+ if ( control . flexContainer . Children != null && control . SelectedItems != null && control . SelectedItems . Any ( ) )
302+ {
303+ foreach ( var item in control . flexContainer . Children )
304+ {
305+ if ( item != null && item is MaterialChips )
306+ ( ( MaterialChips ) item ) . IsSelected = control . SelectedItems . Contains ( ( ( MaterialChips ) item ) . Text ) ;
257307 }
258308 }
259309 }
260310
261311 private static void OnItemsSourceChanged ( BindableObject bindable , object oldValue , object newValue )
262312 {
263313 var control = ( MaterialChipsGroup ) bindable ;
264- control . stcContainer . Children . Clear ( ) ;
314+ control . flexContainer . Children . Clear ( ) ;
265315 if ( ! Equals ( newValue , null ) && newValue is IEnumerable )
266316 {
267317 foreach ( var item in ( IEnumerable ) newValue )
268318 {
319+ // TODO: apply ChipsFlexLayoutBasis???
320+
269321 var materialChips = new MaterialChips
270322 {
271323 HorizontalOptions = LayoutOptions . FillAndExpand ,
@@ -274,6 +326,7 @@ private static void OnItemsSourceChanged(BindableObject bindable, object oldValu
274326 FontFamily = control . FontFamily ,
275327 CornerRadius = control . CornerRadius ,
276328 Padding = control . ChipsPadding ,
329+ Margin = control . ChipsMargin ,
277330 BackgroundColor = control . BackgroundColor ,
278331 TextColor = control . TextColor ,
279332 SelectedBackgroundColor = control . SelectedBackgroundColor ,
@@ -283,12 +336,23 @@ private static void OnItemsSourceChanged(BindableObject bindable, object oldValu
283336 DisabledSelectedBackgroundColor = control . DisabledSelectedBackgroundColor ,
284337 DisabledSelectedTextColor = control . DisabledSelectedTextColor
285338 } ;
286- if ( control . SelectedItem != null )
339+
340+ if ( control . IsMultipleSelection )
341+ {
342+ if ( control . SelectedItems != null && control . SelectedItems . Any ( ) )
343+ materialChips . IsSelected = control . SelectedItems . Contains ( materialChips . Text ) ;
344+ }
345+ else
287346 {
288- materialChips . IsSelected = materialChips . Text . Equals ( control . SelectedItem ) ;
347+ if ( control . SelectedItem != null )
348+ materialChips . IsSelected = materialChips . Text . Equals ( control . SelectedItem ) ;
289349 }
350+
290351 materialChips . IsSelectedChanged += control . MaterialChips_IsSelectedChanged ;
291- control . stcContainer . Children . Add ( materialChips ) ;
352+ control . flexContainer . Children . Add ( materialChips ) ;
353+
354+ if ( control . ChipsFlexLayoutPercentageBasis > 0 && control . ChipsFlexLayoutPercentageBasis <= 1 )
355+ FlexLayout . SetBasis ( materialChips , new FlexBasis ( ( float ) control . ChipsFlexLayoutPercentageBasis , true ) ) ;
292356 }
293357 }
294358 }
@@ -297,27 +361,58 @@ private void MaterialChips_IsSelectedChanged(object sender, EventArgs e)
297361 {
298362 if ( sender is MaterialChips )
299363 {
300- if ( ( ( MaterialChips ) sender ) . IsSelected )
364+ if ( IsMultipleSelection )
301365 {
302- this . SelectedItem = ( ( MaterialChips ) sender ) . Text ;
366+ if ( SelectedItems == null )
367+ SelectedItems = new List < string > ( ) ;
368+
369+ if ( ( ( MaterialChips ) sender ) . IsSelected )
370+ SelectedItems . Add ( ( ( MaterialChips ) sender ) . Text ) ;
371+ else
372+ SelectedItems . Remove ( ( ( MaterialChips ) sender ) . Text ) ;
373+
374+ //bool hasSelected = false;
375+ //if (this.flexContainer.Children != null)
376+ //{
377+ // foreach (var item in this.flexContainer.Children)
378+ // {
379+ // if (item != null && item is MaterialChips && ((MaterialChips)item).IsSelected)
380+ // {
381+ // hasSelected = true;
382+ // break;
383+ // }
384+ // }
385+ //}
386+
387+ //if (!hasSelected)
388+ //{
389+ // ((MaterialChips)sender).IsSelected = true;
390+ //}
303391 }
304-
305- bool hasSelected = false ;
306- if ( this . stcContainer . Children != null )
392+ else
307393 {
308- foreach ( var item in this . stcContainer . Children )
394+ if ( ( ( MaterialChips ) sender ) . IsSelected )
395+ {
396+ this . SelectedItem = ( ( MaterialChips ) sender ) . Text ;
397+ }
398+
399+ bool hasSelected = false ;
400+ if ( this . flexContainer . Children != null )
309401 {
310- if ( item != null && item is MaterialChips && ( ( MaterialChips ) item ) . IsSelected )
402+ foreach ( var item in this . flexContainer . Children )
311403 {
312- hasSelected = true ;
313- break ;
404+ if ( item != null && item is MaterialChips && ( ( MaterialChips ) item ) . IsSelected )
405+ {
406+ hasSelected = true ;
407+ break ;
408+ }
314409 }
315410 }
316- }
317411
318- if ( ! hasSelected )
319- {
320- ( ( MaterialChips ) sender ) . IsSelected = true ;
412+ if ( ! hasSelected )
413+ {
414+ ( ( MaterialChips ) sender ) . IsSelected = true ;
415+ }
321416 }
322417 }
323418 }
@@ -347,7 +442,7 @@ protected override void OnPropertyChanged([CallerMemberName] string propertyName
347442 break ;
348443
349444 case nameof ( this . Padding ) :
350- this . stcContainer . Padding = this . Padding ;
445+ this . flexContainer . Padding = this . Padding ;
351446 break ;
352447
353448 case nameof ( this . AssistiveText ) :
@@ -364,10 +459,9 @@ protected override void OnPropertyChanged([CallerMemberName] string propertyName
364459 case nameof ( this . AssistiveSize ) :
365460 this . lblAssistive . FontSize = this . AssistiveSize ;
366461 break ;
367-
368462 }
369463 }
370464
371465 #endregion Methods
372466 }
373- }
467+ }
0 commit comments