using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Collections.Specialized; using System.Linq; using Xamarin.Forms; using Xamarin.Forms.Xaml; namespace InABox.Mobile { public enum MobileTabStripItemLayout { TextOnly, ImageOnly, Vertical, Horizontal } public class MobileTabStripDataTemplateSelector : DataTemplateSelector { public MobileTabStripItemLayout SelectedLayout { get; set; } public DataTemplate VerticalTemplate { get; set; } public DataTemplate HorizontalTemplate { get; set; } public DataTemplate TextOnlyTemplate { get; set; } public DataTemplate ImageOnlyTemplate { get; set; } protected override DataTemplate OnSelectTemplate (object item, BindableObject container) { return SelectedLayout switch { MobileTabStripItemLayout.ImageOnly => ImageOnlyTemplate, MobileTabStripItemLayout.Vertical => VerticalTemplate, MobileTabStripItemLayout.Horizontal => HorizontalTemplate, _ => TextOnlyTemplate }; } } [XamlCompilation(XamlCompilationOptions.Compile)] public partial class MobileTabStrip { private readonly BindableProperty SelectedBackgroundProperty = BindableProperty.Create( nameof(SelectedBackground), typeof(Color), typeof(MobileTabStrip), XF.Material.Forms.Material.Color.Surface); public Color SelectedBackground { get => (Color)GetValue(SelectedBackgroundProperty); set => SetValue(SelectedBackgroundProperty, value); } private readonly BindableProperty SelectedForegroundProperty = BindableProperty.Create( nameof(SelectedForeground), typeof(Color), typeof(MobileTabStrip), XF.Material.Forms.Material.Color.OnSurface); [TypeConverter(typeof(ColorTypeConverter))] public Color SelectedForeground { get => (Color)GetValue(SelectedForegroundProperty); set => SetValue(SelectedForegroundProperty, value); } private readonly BindableProperty UnselectedBackgroundProperty = BindableProperty.Create( nameof(UnselectedBackground), typeof(Color), typeof(MobileTabStrip), XF.Material.Forms.Material.Color.Primary); [TypeConverter(typeof(ColorTypeConverter))] public Color UnselectedBackground { get => (Color)GetValue(UnselectedBackgroundProperty); set => SetValue(UnselectedBackgroundProperty, value); } private readonly BindableProperty UnselectedForegroundProperty = BindableProperty.Create( nameof(UnselectedForeground), typeof(Color), typeof(MobileTabStrip), XF.Material.Forms.Material.Color.OnPrimary); [TypeConverter(typeof(ColorTypeConverter))] public Color UnselectedForeground { get => (Color)GetValue(UnselectedForegroundProperty); set => SetValue(UnselectedForegroundProperty, value); } // private readonly BindableProperty SeparatorColorProperty = BindableProperty.Create( // nameof(SeparatorColor), // typeof(Color), // typeof(MobileTabStrip), // XF.Material.Forms.Material.Color.Primary); // // public Color SeparatorColor // { // get => (Color)GetValue(SeparatorColorProperty); // set => SetValue(SeparatorColorProperty, value); // } private readonly BindableProperty BorderColorProperty = BindableProperty.Create( nameof(BorderColor), typeof(Color), typeof(MobileTabStrip), XF.Material.Forms.Material.Color.Primary); public Color BorderColor { get => (Color)GetValue(BorderColorProperty); set => SetValue(BorderColorProperty, value); } private readonly BindableProperty CornerRadiusProperty = BindableProperty.Create( nameof(CornerRadius), typeof(float), typeof(MobileTabStrip), 5f); public float CornerRadius { get => (float)GetValue(CornerRadiusProperty); set => SetValue(CornerRadiusProperty, value); } private readonly BindableProperty FontSizeProperty = BindableProperty.Create( nameof(FontSize), typeof(double), typeof(MobileTabStrip), Device.GetNamedSize(NamedSize.Small, typeof(Label))); [TypeConverter(typeof(FontSizeConverter))] public double FontSize { get => (double)GetValue(FontSizeProperty); set => SetValue(FontSizeProperty, value); } private readonly BindableProperty FontAttributesProperty = BindableProperty.Create( nameof(FontAttributes), typeof(FontAttributes), typeof(MobileTabStrip), FontAttributes.None); public FontAttributes FontAttributes { get => (FontAttributes)GetValue(FontAttributesProperty); set => SetValue(FontAttributesProperty, value); } private readonly BindableProperty ItemsLayoutProperty = BindableProperty.Create( nameof(ItemsLayout), typeof(MobileTabStripItemLayout), typeof(MobileTabStrip), MobileTabStripItemLayout.TextOnly); public MobileTabStripItemLayout ItemsLayout { get => (MobileTabStripItemLayout)GetValue(ItemsLayoutProperty); set { _mobileTabStripDataTemplateSelector.SelectedLayout = value; SetValue(ItemsLayoutProperty, value); } } private readonly BindableProperty ImageSizeProperty = BindableProperty.Create( nameof(ImageSize), typeof(Size), typeof(MobileTabStrip), new Size(30,30)); public Size ImageSize { get => (Size)GetValue(ImageSizeProperty); set => SetValue(ImageSizeProperty, value); } public MobileTabStripItem SelectedItem { get => Items.FirstOrDefault(x => x.Selected); set { foreach (var item in Items) item.Selected = item == value; } } public event EventHandler SelectionChanged; public IList Items { get; private set; } public MobileTabStrip() { HeightRequest = 50; var items = new ObservableCollection(); items.CollectionChanged += ItemsChanged; Items = items; InitializeComponent(); BindableLayout.SetItemsSource(_grid, Items); } private void ItemsChanged(object sender, NotifyCollectionChangedEventArgs e) { _grid.ColumnDefinitions.Clear(); foreach (var item in Items) { item.Index = _grid.ColumnDefinitions.Count; _grid.ColumnDefinitions.Add(new ColumnDefinition() { Width = GridLength.Star }); } Device.BeginInvokeOnMainThread(() => { SelectedItem ??= Items.FirstOrDefault(); }); } private void DoTap(object sender, EventArgs e) { Device.BeginInvokeOnMainThread(() => { foreach (var item in Items) item.Selected = item == (sender as BindableObject)?.BindingContext; OnPropertyChanged(nameof(Items)); SelectionChanged?.Invoke(this,EventArgs.Empty); }); } } }