Как реализовать ListView и отобразить данные в нём?
ListView в Xamarin.Forms — это элемент управления, предназначенный для отображения прокручиваемого списка данных. Он позволяет визуализировать коллекцию объектов, настраивать их внешний вид с помощью шаблонов, обрабатывать выбор элементов, обновлять содержимое и выполнять действия при нажатии. Несмотря на появление более современного CollectionView, ListView по-прежнему широко используется и поддерживается.
1. Основные свойства ListView
-
ItemsSource — коллекция данных, которые будут отображаться.
-
ItemTemplate — шаблон визуализации каждого элемента.
-
SelectedItem — выбранный элемент списка.
-
HasUnevenRows — если true, строки могут иметь разную высоту.
-
SeparatorVisibility — отображение разделителей между элементами.
-
IsPullToRefreshEnabled — включает/отключает поддержку «потяни, чтобы обновить».
-
IsRefreshing — флаг, указывающий на текущее состояние обновления.
-
ItemTapped / ItemSelected — события выбора элемента.
2. Создание модели данных
public class Contact
{
public string Name { get; set; }
public string Phone { get; set; }
public string ImageUrl { get; set; } // для отображения фото
}
3. Создание ViewModel с ObservableCollection
ViewModel предоставляет список объектов для отображения в ListView.
public class ContactsViewModel : INotifyPropertyChanged
{
public ObservableCollection<Contact> Contacts { get; }
public ContactsViewModel()
{
Contacts = new ObservableCollection<Contact>
{
new Contact { Name = "Алексей", Phone = "123-456", ImageUrl = "https://example.com/photo1.jpg" },
new Contact { Name = "Мария", Phone = "987-654", ImageUrl = "https://example.com/photo2.jpg" }
};
}
public event PropertyChangedEventHandler PropertyChanged;
}
4. Установка BindingContext
Чтобы ListView мог получить данные, нужно установить BindingContext страницы:
В XAML:
<ContentPage.BindingContext>
<local:ContactsViewModel />
</ContentPage.BindingContext>
В C#:
BindingContext = new ContactsViewModel();
5. Определение ListView в XAML
<ListView ItemsSource="{Binding Contacts}"
HasUnevenRows="True"
ItemSelected="OnItemSelected"
SeparatorVisibility="Default">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Orientation="Horizontal" Padding="10">
<Image Source="{Binding ImageUrl}" WidthRequest="50" HeightRequest="50"/>
<StackLayout VerticalOptions="Center">
<Label Text="{Binding Name}" FontAttributes="Bold" />
<Label Text="{Binding Phone}" FontSize="Small" />
</StackLayout>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Этот шаблон отобразит фотографию, имя и номер телефона для каждого контакта.
6. Обработка выбора элемента
В Code-behind можно реализовать обработчик события ItemSelected:
private async void OnItemSelected(object sender, SelectedItemChangedEventArgs e)
{
if (e.SelectedItem is Contact selectedContact)
{
await DisplayAlert("Контакт", $"{selectedContact.Name}\\n{selectedContact.Phone}", "OK");
((ListView)sender).SelectedItem = null; // сброс выбора
}
}
7. Отображение простого списка без шаблона
Если коллекция содержит примитивные типы, например List<string>, можно использовать простую привязку:
public ObservableCollection<string> Items { get; } = new ObservableCollection<string>
{
"Элемент 1", "Элемент 2", "Элемент 3"
};
<ListView ItemsSource="{Binding Items}" />
8. Pull-to-Refresh (обновление списка)
ListView поддерживает жест обновления с прокруткой вниз:
<ListView ItemsSource="{Binding Contacts}"
IsPullToRefreshEnabled="True"
IsRefreshing="{Binding IsBusy}"
RefreshCommand="{Binding RefreshCommand}" />
public ICommand RefreshCommand { get; }
public ContactsViewModel()
{
RefreshCommand = new Command(ExecuteRefresh);
}
private async void ExecuteRefresh()
{
IsBusy = true;
// Обновление списка
await Task.Delay(2000); // имитация загрузки с сервера
Contacts.Add(new Contact { Name = "Новый", Phone = "111-222", ImageUrl = "https://example.com/photo3.jpg" });
IsBusy = false;
}
9. Удаление и добавление элементов
ObservableCollection автоматически обновляет UI при изменениях:
Contacts.Add(new Contact { Name = "Новый контакт", Phone = "555-333" });
Contacts.RemoveAt(0);
10. Использование ListView в MVVM
Для полной интеграции с MVVM:
-
Используйте команды (ICommand) вместо событий.
-
Не обрабатывайте логику в Code-behind.
-
Выбор элемента можно передавать через привязку SelectedItem:
<ListView ItemsSource="{Binding Contacts}"
SelectedItem="{Binding SelectedContact, Mode=TwoWay}" />
private Contact selectedContact;
public Contact SelectedContact
{
get => selectedContact;
set
{
selectedContact = value;
OnPropertyChanged(nameof(SelectedContact));
if (value != null)
{
// Логика при выборе
}
}
}
11. Использование контекстных действий (Context Actions)
Контекстные действия отображаются при свайпе строки (только на Android и iOS).
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<ViewCell.ContextActions>
<MenuItem Text="Удалить"
Command="{Binding BindingContext.DeleteCommand, Source={x:Reference Page}}"
CommandParameter="{Binding .}"
IsDestructive="True" />
</ViewCell.ContextActions>
<StackLayout Padding="10">
<Label Text="{Binding Name}" />
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
12. Кеширование ячеек (CachingStrategy)
По умолчанию ListView кеширует ячейки. Можно указать стратегию:
<ListView CachingStrategy="RecycleElement" />
-
RecycleElement — экономит память.
-
RetainElement — создает новые экземпляры (меньше багов при сложной логике).
13. Замена ListView на CollectionView
Хотя ListView до сих пор актуален, CollectionView рекомендуется Microsoft как более современный:
-
Более производительный.
-
Поддержка Grid и Horizontal layout.
-
Гибкая структура и лучшее управление шаблонами.
Тем не менее, ListView остаётся удобным для простых списков и быстрого прототипирования.
ListView предоставляет богатый функционал для отображения коллекций данных в мобильных приложениях Xamarin.Forms. Его мощные возможности по кастомизации шаблонов, выбору и обновлению данных делают его надёжным инструментом при разработке пользовательских интерфейсов.