Суть вопроса звучит предельно просто: как можно группировать элементы в ListView (полный текст вопроса можно найти здесь). Однако на самом деле создание групп – не такая элементарная задача, как могло бы показаться.
Чтобы найти ответ на этот вопрос, нам потребуется пройти несколько этапов. Если отталкиваться от примера, приведенного в вопросе по ссылке выше, то в итоге мы должны будем получить список разных моделей телефонов, сгруппированных по производителю. Нам нужен список, содержащий в себе ключ и значение, которое в свою очередь представляет собой ещё один список. Всё это вместе и будет составлять группу. В нашем примере ключ может быть представлен одной строкой кода, но при желании его можно расширить и до массивного объекта. Как мы увидим далее, привязать необходимые данные можно с помощью дата-биндинга.
Модель группы
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | public class PhoneGroup : ObservableCollection<Phone> { public string Name { get; private set; } public PhoneGroup(string name) : base() { Name = name; } public PhoneGroup(string name, IEnumerable<Phone> source) : base(source) { Name = name; } } |
В коде выше можно увидеть модель, которую я ввел таким образом, чтобы она работала как группа. При этом я унаследовал базовый класс ObservableCollection, который содержит модель Phone. Модель Phone это случайный объект с несколькими простыми свойствами. В частности, этот объект унаследует свойство Name. Таким образом, мы получаем базовый класс ObservableCollect с ключом, по которому группируется список.
Страница
Чтобы далеко не ходить, я взял файл отделенного кода моей страницы в качестве ViewModel, но этот принцип работает и в случае настоящей отдельной модели представления.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | using System.Collections.ObjectModel; using GroupingListViewSample.Models; using GroupingListViewSample.ViewModels; using Xamarin.Forms; namespace GroupingListViewSample { public partial class GroupingListViewSamplePage : ContentPage { public ObservableCollection<PhoneGroup> PhonesList { get; set; } = new ObservableCollection<PhoneGroup>(); public GroupingListViewSamplePage() { InitializeComponent(); PhonesList.Add(new PhoneGroup("Apple", new[]{ new Phone { Title = "iPhone 6s", Price = 50000 }, new Phone { Title = "iPhone 7", Price = 38000 }})); PhonesList.Add(new PhoneGroup("Huawei", new[]{ new Phone { Title = "Huawei P10", Price = 10000 }, new Phone { Title = "Huawei Mate 8", Price = 29000 }})); PhonesList.Add(new PhoneGroup("Samsung", new[]{ new Phone { Title = "Galaxy S8", Price = 60000 }, new Phone { Title = "Galaxy S7 Edge", Price = 50000 }})); BindingContext = this; } } } |
Отметьте, как я создал свойство, представляющее собой ещё один ObservableCollection, который содержит модель группы. Таким образом мы получаем коллекцию объектов, которые сгруппированы вместе. Я добавляю к ним несколько моделей вручную в конструкторе. Но в реальной жизни вам скорее всего придётся получать данные онлайн и группировать их в коллекцию с помощью LINQ-запросов. И, наконец, я задаю свойства Binding Context в файле отделенного кода, чтобы XAML-разметка могла видеть нашу коллекцию.
В XAML я задаю свойства ListView, как показано в коде выше.
1 2 3 4 5 6 7 8 9 10 11 12 13 | <?xml version="1.0" encoding="utf-8"?> <ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:local="clr-namespace:GroupingListViewSample" x:Class="GroupingListViewSample.GroupingListViewSamplePage"> <ListView ItemsSource="{Binding PhonesList}" IsGroupingEnabled="True" GroupDisplayBinding="{Binding Name}"> <ListView.ItemTemplate> <DataTemplate> <TextCell Text="{Binding Title}" /> </DataTemplate> </ListView.ItemTemplate> </ListView> </ContentPage> |
Два свойства, на которые следует обратить внимание, — это IsGroupingEnabled и GroupDisplayBinding. Чтобы включить группировку, достаточно просто задать IsGroupingEnabled значение true. Затем с помощью GroupDisplayBinding вы сможете привязывать данные к свойству модели группы, которое отображается в заголовке группы. В нашем случае это будет наименование компании, то есть Apple, Huawei или Samsung. И это всё, что вам понадобится для введения групп!
На скриншоте ниже видно, как наш код отображается в симуляторе iOS.
К слову, в приложениях на iOS можно добавить ещё одну интересную функцию, а именно выпадающий список с буквами. Это можно реализовать биндингом со свойством GroupShortNameBinding. Обычно в этом списке отображаются только первые буквы групп. Просто привяжите данные к первой букве каждой группы или введите отдельное свойство для этого, и всё готово.
Подводя итог
В статье мы разобрали, как интегрировать модели группировки и как вообще делать возможной группировки в ListView. Если вы не любитель изобретать велосипед, то за более детальной информацией обращайтесь к библиотеке MVVM Helpers. Там вы найдете класс ObservableRangeCollection, который позволит вам с легкостью добавлять или заменять значения в ObservableCollection. К тому же, там вы найдете модель Grouping, которая значительно облегчит процесс создания групп в ListView. Удачи!
Источник: blog.verslu.is
Написать ответ