简体   繁体   中英

Group ListView by a component on a JSON in Xamarin.Forms

I'm trying to group items from a JSON in the ListView.

My JSON is stored in an web repository, I already pulled it from the server and listed it but ungrouped.

I've read a lot of tutorials about how to group C# List but none of them solved my problem.

Here's the JSON:

[
  {
    "status": "Status 1",
    "erpCode": "1901",
    "name": "Name 1",
    "statusReportDate": "24/08/2018",
    "statusReportDescription": "Description 1"
  },
  {
    "status": "Status 2",
    "erpCode": "2160",
    "name": "Name 2",
    "statusReportDate": "24/08/2018",
    "statusReportDescription": "Description 2"
  },
  {
    "status": "Status 2",
    "erpCode": "543",
    "name": "Name 3",
    "statusReportDate": "24/08/2018",
    "statusReportDescription": "Description 3"
  }
]

My method that pull the JSON from a web repository and convert it to a List and ObservableCollection:

protected async void OnGetList()
{
    if (CrossConnectivity.Current.IsConnected)
    {

        try
        {
            //Getting JSON data from the Web
            var content = await _client.GetStringAsync(Url);

            //We deserialize the JSON data from this line
            var list = JsonConvert.DeserializeObject<List<Company>>(content);

            //After deserializing , we store our data in the List called ObservableCollection
            ObservableCollection<Company> collection = new ObservableCollection<Company>(list);
            myList.ItemsSource = collection;

        }
        catch (Exception ey)
        {
            Debug.WriteLine("" + ey);
        }
    }
}

XAML ListView:

<ListView x:Name="myList" 
                  HasUnevenRows="True" 
                  ItemSelected="MyList_ItemSelected">
    <ListView.ItemTemplate>
        <DataTemplate>
            <ViewCell>
                <StackLayout Orientation="Horizontal" Margin="5" HorizontalOptions="Fill">
                    <Button Text="{Binding erpCode}"/>

                    <StackLayout HorizontalOptions="Fill">
                        <Grid>
                            <Label Text="{Binding name}"/>
                            <Label Text="{Binding statusReportDate}"/>
                        </Grid>
                        <Label Text="{Binding statusReportDescription}"/>
                    </StackLayout>
                </StackLayout>
            </ViewCell>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

I want to group it by "status" and print something like this:

Status 1

Name 1

Status 2

Name 2

Name 3

Status N

Name n1

Name n2

Name n3

...

Check out this article: https://xamarinhelp.com/xamarin-forms-listview-grouping/

But better to use ObservableCollection , where the above article uses List .

So you have to create an ObservableCollection of a type that is a subclass of ObservableCollection .

First create a type that subclasses ObservableCollection that will hold one group of companies by status:

public class CompanyByStatusList : ObservableCollection<Company>
{
    public string Status { get; set; }
    public ObservableCollection<Company> Companies => this;
}

Then create an ObservableCollection of CompanyByStatusList . This will be your ItemsSource for your ListView .

public ObservableCollection<CompanyByStatusList> CompanyList { get; set; }

Then you want to create a CompanyByStatusList for each status that holds all of the companies in that specific status, and then add each of those CompanyByStatusList to the CompanyList collection. Make sure to set the Status property of each CompanyByStatusList

And make sure to set IsGroupingEnabled="true" on your ListView . ListView xaml:

<ListView ItemsSource="{Binding CompanyList}"
      IsGroupingEnabled="true" 
         HasUnevenRows="true">
    <ListView.GroupHeaderTemplate>
        <DataTemplate>
            <ViewCell>
                <Label Text="{Binding Status}" />
            </ViewCell>
        </DataTemplate>
    </ListView.GroupHeaderTemplate>

    <ListView.ItemTemplate>
        <DataTemplate>
            <ViewCell>
                <StackLayout Orientation="Horizontal" Margin="5" HorizontalOptions="Fill">
                    <Button Text="{Binding erpCode}"/>

                    <StackLayout HorizontalOptions="Fill">
                        <StackLayout Orientation="Horizontal">
                            <Label Text="{Binding name}"/>
                            <Label Text="{Binding statusReportDate}"/>
                        </StackLayout>
                        <Label Text="{Binding statusReportDescription}"/>
                    </StackLayout>
                </StackLayout>
            </ViewCell>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM