Руководство / Списки

Данных может быть много. Смонтированных строк — нет.

ListView<T> использует нативную виртуализацию UI Toolkit и монтирует Widget только для видимых и подготовленных к переиспользованию строк.

Column для малого набора. ListView для растущего.

Column + ScrollView

Маленький статичный список

Все дети монтируются сразу. Подходит для настроек или нескольких карточек.

ListView<T>

Большая коллекция

Монтируются только нужные строки; переиспользование выполняет нативный ListView.

Начните с типизированного builder строки.

Для строк одинаковой высоты укажите itemHeight. Если высота зависит от содержимого, не передавайте её — будет использована dynamic-height виртуализация.

ProjectsList.cs
new ListView<Project>(
  projects,
  project => new ProjectRow(project),
  itemHeight: 56f);

Добавляйте Key строкам с состоянием.

Если строка владеет фокусом, подписками или локальным State, дайте ей уникальный стабильный ключ. При вставке и сортировке ключ позволяет перенести совместимую строку за тем же объектом данных.

ProjectsList.cs
new ListView<Project>(
  projects,
  project => new ProjectRow(project),
  itemHeight: 56f,
  itemKey: project => new WidgetKey(project.Id));
Не используйте индекс как Key.

После вставки индекс станет принадлежать другому объекту. Берите идентификатор из данных: project.Id, message.Id и аналогичный.

Не изменяйте реактивную коллекцию на месте.

Храните State<IReadOnlyList<T>> и присваивайте новое значение целиком. Мутация обычного List сама по себе не отправит уведомление.

Список отображает выбор, но не владеет им.

Выбранные элементы хранятся как ключи во внешнем State. Пользовательский ввод сначала обновляет State, затем вызывает callback.

ProjectsList.cs
var selected = new State<IReadOnlyList<WidgetKey>>(
  Array.Empty<WidgetKey>());

new ListView<Project>(
  projects, BuildRow,
  itemKey: project => new WidgetKey(project.Id),
  selectionMode: ListSelectionMode.Multiple,
  selectedKeys: selected);

Сохраните controller, если позиция имеет значение.

ListViewController должен жить там же, где конфигурация списка, а не создаваться в Build.

ProjectsList.cs
private readonly ListViewController _controller = new();

_controller.JumpTo(320f);
_controller.ScrollTo(new WidgetKey(projectId));
Дальше: навигация и оверлеи →