MobileTabStrip.xaml.cs 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Collections.ObjectModel;
  4. using System.Collections.Specialized;
  5. using System.Linq;
  6. using Xamarin.Forms;
  7. using Xamarin.Forms.Xaml;
  8. namespace InABox.Mobile
  9. {
  10. public enum MobileTabStripItemLayout
  11. {
  12. TextOnly,
  13. ImageOnly,
  14. Vertical,
  15. Horizontal
  16. }
  17. public class MobileTabStripDataTemplateSelector : DataTemplateSelector
  18. {
  19. public MobileTabStripItemLayout SelectedLayout { get; set; }
  20. public DataTemplate VerticalTemplate { get; set; }
  21. public DataTemplate HorizontalTemplate { get; set; }
  22. public DataTemplate TextOnlyTemplate { get; set; }
  23. public DataTemplate ImageOnlyTemplate { get; set; }
  24. protected override DataTemplate OnSelectTemplate (object item, BindableObject container)
  25. {
  26. return SelectedLayout switch
  27. {
  28. MobileTabStripItemLayout.ImageOnly => ImageOnlyTemplate,
  29. MobileTabStripItemLayout.Vertical => VerticalTemplate,
  30. MobileTabStripItemLayout.Horizontal => HorizontalTemplate,
  31. _ => TextOnlyTemplate
  32. };
  33. }
  34. }
  35. [XamlCompilation(XamlCompilationOptions.Compile)]
  36. public partial class MobileTabStrip
  37. {
  38. private readonly BindableProperty SelectedBackgroundProperty = BindableProperty.Create(
  39. nameof(SelectedBackground),
  40. typeof(Color),
  41. typeof(MobileTabStrip),
  42. XF.Material.Forms.Material.Color.Surface);
  43. public Color SelectedBackground
  44. {
  45. get => (Color)GetValue(SelectedBackgroundProperty);
  46. set => SetValue(SelectedBackgroundProperty, value);
  47. }
  48. private readonly BindableProperty SelectedForegroundProperty = BindableProperty.Create(
  49. nameof(SelectedForeground),
  50. typeof(Color),
  51. typeof(MobileTabStrip),
  52. XF.Material.Forms.Material.Color.OnSurface);
  53. [TypeConverter(typeof(ColorTypeConverter))]
  54. public Color SelectedForeground
  55. {
  56. get => (Color)GetValue(SelectedForegroundProperty);
  57. set => SetValue(SelectedForegroundProperty, value);
  58. }
  59. private readonly BindableProperty UnselectedBackgroundProperty = BindableProperty.Create(
  60. nameof(UnselectedBackground),
  61. typeof(Color),
  62. typeof(MobileTabStrip),
  63. XF.Material.Forms.Material.Color.Primary);
  64. [TypeConverter(typeof(ColorTypeConverter))]
  65. public Color UnselectedBackground
  66. {
  67. get => (Color)GetValue(UnselectedBackgroundProperty);
  68. set => SetValue(UnselectedBackgroundProperty, value);
  69. }
  70. private readonly BindableProperty UnselectedForegroundProperty = BindableProperty.Create(
  71. nameof(UnselectedForeground),
  72. typeof(Color),
  73. typeof(MobileTabStrip),
  74. XF.Material.Forms.Material.Color.OnPrimary);
  75. [TypeConverter(typeof(ColorTypeConverter))]
  76. public Color UnselectedForeground
  77. {
  78. get => (Color)GetValue(UnselectedForegroundProperty);
  79. set => SetValue(UnselectedForegroundProperty, value);
  80. }
  81. // private readonly BindableProperty SeparatorColorProperty = BindableProperty.Create(
  82. // nameof(SeparatorColor),
  83. // typeof(Color),
  84. // typeof(MobileTabStrip),
  85. // XF.Material.Forms.Material.Color.Primary);
  86. //
  87. // public Color SeparatorColor
  88. // {
  89. // get => (Color)GetValue(SeparatorColorProperty);
  90. // set => SetValue(SeparatorColorProperty, value);
  91. // }
  92. private readonly BindableProperty BorderColorProperty = BindableProperty.Create(
  93. nameof(BorderColor),
  94. typeof(Color),
  95. typeof(MobileTabStrip),
  96. XF.Material.Forms.Material.Color.Primary);
  97. public Color BorderColor
  98. {
  99. get => (Color)GetValue(BorderColorProperty);
  100. set => SetValue(BorderColorProperty, value);
  101. }
  102. private readonly BindableProperty CornerRadiusProperty = BindableProperty.Create(
  103. nameof(CornerRadius),
  104. typeof(float),
  105. typeof(MobileTabStrip),
  106. 5f);
  107. public float CornerRadius
  108. {
  109. get => (float)GetValue(CornerRadiusProperty);
  110. set => SetValue(CornerRadiusProperty, value);
  111. }
  112. private readonly BindableProperty FontSizeProperty = BindableProperty.Create(
  113. nameof(FontSize),
  114. typeof(double),
  115. typeof(MobileTabStrip),
  116. Device.GetNamedSize(NamedSize.Small, typeof(Label)));
  117. [TypeConverter(typeof(FontSizeConverter))]
  118. public double FontSize
  119. {
  120. get => (double)GetValue(FontSizeProperty);
  121. set => SetValue(FontSizeProperty, value);
  122. }
  123. private readonly BindableProperty FontAttributesProperty = BindableProperty.Create(
  124. nameof(FontAttributes),
  125. typeof(FontAttributes),
  126. typeof(MobileTabStrip),
  127. FontAttributes.None);
  128. public FontAttributes FontAttributes
  129. {
  130. get => (FontAttributes)GetValue(FontAttributesProperty);
  131. set => SetValue(FontAttributesProperty, value);
  132. }
  133. private readonly BindableProperty ItemsLayoutProperty = BindableProperty.Create(
  134. nameof(ItemsLayout),
  135. typeof(MobileTabStripItemLayout),
  136. typeof(MobileTabStrip),
  137. MobileTabStripItemLayout.TextOnly);
  138. public MobileTabStripItemLayout ItemsLayout
  139. {
  140. get => (MobileTabStripItemLayout)GetValue(ItemsLayoutProperty);
  141. set
  142. {
  143. _mobileTabStripDataTemplateSelector.SelectedLayout = value;
  144. SetValue(ItemsLayoutProperty, value);
  145. }
  146. }
  147. private readonly BindableProperty ImageSizeProperty = BindableProperty.Create(
  148. nameof(ImageSize),
  149. typeof(Size),
  150. typeof(MobileTabStrip),
  151. new Size(30,30));
  152. public Size ImageSize
  153. {
  154. get => (Size)GetValue(ImageSizeProperty);
  155. set => SetValue(ImageSizeProperty, value);
  156. }
  157. public MobileTabStripItem SelectedItem
  158. {
  159. get => Items.FirstOrDefault(x => x.Selected);
  160. set
  161. {
  162. foreach (var item in Items)
  163. item.Selected = item == value;
  164. }
  165. }
  166. public event EventHandler SelectionChanged;
  167. public IList<MobileTabStripItem> Items { get; private set; }
  168. public MobileTabStrip()
  169. {
  170. HeightRequest = 50;
  171. var items = new ObservableCollection<MobileTabStripItem>();
  172. items.CollectionChanged += ItemsChanged;
  173. Items = items;
  174. InitializeComponent();
  175. BindableLayout.SetItemsSource(_grid, Items);
  176. }
  177. private void ItemsChanged(object sender, NotifyCollectionChangedEventArgs e)
  178. {
  179. _grid.ColumnDefinitions.Clear();
  180. foreach (var item in Items)
  181. {
  182. item.Index = _grid.ColumnDefinitions.Count;
  183. _grid.ColumnDefinitions.Add(new ColumnDefinition() { Width = GridLength.Star });
  184. }
  185. Device.BeginInvokeOnMainThread(() =>
  186. {
  187. SelectedItem ??= Items.FirstOrDefault();
  188. });
  189. }
  190. private void DoTap(object sender, EventArgs e)
  191. {
  192. Device.BeginInvokeOnMainThread(() =>
  193. {
  194. foreach (var item in Items)
  195. item.Selected = item == (sender as BindableObject)?.BindingContext;
  196. OnPropertyChanged(nameof(Items));
  197. SelectionChanged?.Invoke(this,EventArgs.Empty);
  198. });
  199. }
  200. }
  201. }