using static Blahblah.FlowerApp.Extensions; namespace Blahblah.FlowerApp.Controls; class ItemSelectorPage<K, T> : ContentPage where T : IdTextItem<K> { public EventHandler<T>? Selected; public ItemSelectorPage(string title, T[] source, bool multiple = false, K[]? selected = null, string display = nameof(IdTextItem<K>.Text), string? detail = null) { Title = title; var itemsSource = source.Select(t => new SelectableItem<T> { Item = t, IsSelected = selected != null && selected.Contains(t.Id) }).ToArray(); var list = new ListView { SelectionMode = ListViewSelectionMode.None, ItemsSource = itemsSource, ItemTemplate = new DataTemplate(() => { var content = new Grid { Margin = new Thickness(12, 0), ColumnSpacing = 12, ColumnDefinitions = { new(30), new(GridLength.Star), new(GridLength.Auto) }, Children = { new SecondaryLabel { VerticalOptions = LayoutOptions.Center, HorizontalOptions = LayoutOptions.Center, Text = Res.Check, FontFamily = "FontAwesome" } .Binding(IsVisibleProperty, nameof(SelectableItem<T>.IsSelected)), new Label { VerticalOptions = LayoutOptions.Center } .Binding(Label.TextProperty, $"{nameof(SelectableItem<T>.Item)}.{display}") .GridColumn(1) } }; if (detail != null) { content.Children.Add( new SecondaryLabel { VerticalOptions = LayoutOptions.Center } .Binding(Label.TextProperty, $"{nameof(SelectableItem<T>.Item)}.{detail}") .GridColumn(2)); } return new ViewCell { View = content }; }) }; list.ItemTapped += List_ItemTapped; Content = list; } private async void List_ItemTapped(object? sender, ItemTappedEventArgs e) { if (e.Item is SelectableItem<T> item) { Selected?.Invoke(this, item.Item); await Navigation.PopAsync(); } } } class SelectableItem<T> : BindableObject { public static BindableProperty IsSelectedProperty = CreateProperty<bool, SelectableItem<T>>(nameof(IsSelected)); public static BindableProperty ItemProperty = CreateProperty<T, SelectableItem<T>>(nameof(Item)); public bool IsSelected { get => (bool)GetValue(IsSelectedProperty); set => SetValue(IsSelectedProperty, value); } public T Item { get => (T)GetValue(ItemProperty); set => SetValue(ItemProperty, value); } } class IdTextItem<T> : BindableObject { public static BindableProperty IdProperty = CreateProperty<T, IdTextItem<T>>(nameof(Id)); public static BindableProperty TextProperty = CreateProperty<string, IdTextItem<T>>(nameof(Text)); public static BindableProperty DetailProperty = CreateProperty<string?, IdTextItem<T>>(nameof(Detail)); public T Id { get => (T)GetValue(IdProperty); set => SetValue(IdProperty, value); } public string Text { get => (string)GetValue(TextProperty); set => SetValue(TextProperty, value); } public string? Detail { get => (string?)GetValue(DetailProperty); set => SetValue(DetailProperty, value); } }