flower-story/FlowerApp/Controls/ItemSelectorPage.cs
2023-08-02 23:45:04 +08:00

124 lines
4.0 KiB
C#

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);
}
}