using System; using System.Collections.Generic; using System.Linq; using System.Text.RegularExpressions; using Xamarin.CommunityToolkit.UI.Views; using Xamarin.Forms; using Xamarin.Forms.Xaml; namespace comal.timesheets { public delegate void ExpanderViewSelectionChanged(object sender, EventArgs args); [XamlCompilation(XamlCompilationOptions.Compile)] public partial class ExpanderView : ContentView { private ExpanderViewData _data; public ExpanderViewData Data { get => _data; set { _data = value; Load(); } } public Color SelectedColor { get; set; } public Color UnselectedColor { get; set; } public event ExpanderViewSelectionChanged SelectionChanged; public ExpanderView() { InitializeComponent(); SelectedColor = Color.Red; UnselectedColor = Color.Silver; } public void Load() { Stack.Children.Clear(); if (Data == null) return; foreach (var group in Data.Groups) { var expander = new Expander(); expander.HorizontalOptions = LayoutOptions.Start; expander.Header = CreateHeader(group,(o, e) => { (o as Frame).Margin = new Thickness(0, 0, expander.IsExpanded ? 0 : 10, 0); foreach (var exp in Stack.Children.Where(x => x != expander)) exp.IsVisible = expander.IsExpanded; expander.ForceUpdateSize(); if (!expander.IsExpanded) Scroll.ScrollToAsync(0, 0, false); else Scroll.ScrollToAsync(expander, ScrollToPosition.MakeVisible, false); }); expander.Content = CreateList(group); Stack.Children.Add(expander); } } private ContentView CreateHeader(ExpanderViewGroup group, EventHandler ontapped) { Frame frame = new Frame(); frame.BackgroundColor = Color.White; frame.HasShadow = false; frame.CornerRadius = 15; frame.BorderColor = Color.Black; frame.Padding = new Thickness(5, 5, 10, 5); frame.HorizontalOptions = LayoutOptions.Fill; frame.MinimumHeightRequest = 40; TapGestureRecognizer headerTap = new TapGestureRecognizer() { NumberOfTapsRequired = 1 }; headerTap.Tapped += ontapped; frame.GestureRecognizers.Add(headerTap); Grid grid = new Grid(); grid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto }); grid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto }); if (group.Image != null) { Image image = new Image() { Source = group.Image }; image.WidthRequest = 30; image.HeightRequest = 30; image.SetValue(Grid.ColumnProperty, 0); grid.Children.Add(image); } Label label = new Label() { Text = group.Description, FontAttributes = FontAttributes.Bold, VerticalTextAlignment = TextAlignment.Center, HorizontalTextAlignment = TextAlignment.Center }; label.FontSize = 18; label.SetValue(Grid.ColumnProperty, 1); grid.Children.Add(label); frame.Content = grid; return frame; } private View CreateList(ExpanderViewGroup group) { ListView result = new ListView(); result.SelectionMode = ListViewSelectionMode.None; result.HorizontalOptions = LayoutOptions.Fill; result.ItemTemplate = new DataTemplate(() => { Button button = new Button(); button.SetBinding(Button.TextProperty, "Description"); button.Clicked += ExpanderViewItem_Clicked; button.MinimumHeightRequest = 40; button.TextColor = Color.Black; button.CornerRadius = 15; button.BorderColor = UnselectedColor; button.BackgroundColor = UnselectedColor; button.Margin = new Thickness(2, 2, 10, 2); button.HorizontalOptions = LayoutOptions.Fill; return new ViewCell { View = button }; }); result.ItemsSource = group.Items; return result; } private void ExpanderViewItem_Clicked(object sender, EventArgs e) { var button = (sender as Button); var item = button.BindingContext as ExpanderViewItem; item.Selected = !item.Selected; button.BackgroundColor = item.Selected ? SelectedColor : UnselectedColor; button.BorderColor = button.BackgroundColor; SelectionChanged?.Invoke(this,new EventArgs()); } } }