adospace / reactorui-maui

MauiReactor is a MVU UI framework built on top of .NET MAUI
MIT License
586 stars 49 forks source link

Sample ListView IsGroupingEnabled #77

Closed Code-DJ closed 1 year ago

Code-DJ commented 1 year ago

Hi @adospace I am having a hard time creating the ItemsSource for ListView with IsGroupingEnabled(true).

I understand that without grouping we return one ViewCell so the internal system can reuse the ViewCells. Why does IsGroupingEnabled also return a ViewCell?

Syntactically this works but I am confused as to what should ViewCell return?

new ListView()
                .IsGroupingEnabled(true)
                .ItemsSource(State.GroupedItems, RenderGroup)
                .HFill()
                .VFill()
:
:

private ViewCell RenderGroup(GroupedCollection<string, Contact> groupedContacts) => new ViewCell
{
};

I am trying to recreate the standard iOS grouped contact list:

adospace commented 1 year ago

Hi, honestly, the ListView implementation quality in MauiReactor is a bit behind. For example, you can't customize the group header, the listview header, or the footer. It should be reasonably easy to provide support for all of them, I'll keep you updated here,

Thanks

adospace commented 1 year ago

Just pushed some fixes and enhancements for the ListView. I've added a sample page to the Test App project showing how to group list view items. If you need the Nuget package please wait a couple of hours.

MauiReactor_ListView

class ListViewExtendedTestPageState
{
    public Person? SelectedPerson { get; set; }
}

class ListViewExtendedTestPage : Component<ListViewExtendedTestPageState>
{
    public override VisualNode Render()
    {
        return new ContentPage("ListView Extended Test (BETA)")
        {
            new ListView(MauiControls.ListViewCachingStrategy.RecycleElementAndDataTemplate)
                .IsGroupingEnabled(true)
                .ItemsSource<ListView, GroupOfPerson, Person>(GroupOfPerson.All, RenderGroup, RenderItem)
                .SeparatorVisibility(MauiControls.SeparatorVisibility.None)
                .OnItemSelected(OnSelectedItem)
                //NOTE: Header/Footer not working under .net 7
                //https://github.com/dotnet/maui/issues/13560
                //https://github.com/dotnet/maui/issues/12312
                //.Header(new Label("Header"))
                //.Footer(new Label("Footer"))
        };
    }

    private void OnSelectedItem(object? sender, SelectedItemChangedEventArgs args)
    {
        SetState(s => s.SelectedPerson = args.SelectedItem as Person);
    }

    private ViewCell RenderGroup(GroupOfPerson person)
    {
        return new ViewCell
        {
            new Label(person.Initial)
                .FontSize(14.0)
                .FontAttributes(MauiControls.FontAttributes.Bold)
                .Margin(5)
                .BackgroundColor(Colors.LightGray),
        };
    }

    private ViewCell RenderItem(Person person)
    {
        return new ViewCell
        {
            new Label($"{person.FirstName} {person.LastName}")
                .FontSize(14.0)
                .FontAttributes(MauiControls.FontAttributes.Bold)
                .Padding(5)
                .VerticalTextAlignment(TextAlignment.Center)
        };
    }
}
Code-DJ commented 1 year ago

Just a side note, don't we lose access to the NativeControl due to single parameter constructor MauiControls.ListViewCachingStrategy.RecycleElementAndDataTemplate?

BTW works well. Thank you!

adospace commented 1 year ago

Ops, you're right, I'm reopening the ticket, I'll fix it tomorrow. thanks for the hint!

adospace commented 1 year ago

Fixed in 1.0.128