Рекомендации по использованию элемента управления "Галерея" в приложениях на основе холста

Галерея — это единственный элемент управления в приложениях на основе холста, который может создавать другие элементы управления. У него есть своя область действия. Эти расширенные функции могут привести к неожиданному поведению, если Галерея настроена неправильно. В этой статье рассматриваются рекомендации и передовые методы при работе с элементами управления Gallery.

Tip

Рекомендуется использовать современные элементы управления в элементах коллекции, где это возможно. Современные элементы управления разработаны так, чтобы свести к минимуму распространенные проблемы, такие как непреднамеренные срабатывания OnChange, и обеспечить лучшую доступность и более широкие возможности стилизации. Вы также можете использовать Copilot в Power Apps для автоматического создания макета коллекции и подключения к данным.

Легко создать нестабильное поведение, если OnChange или OnSelect дочерних элементов управления изменяет значение Items родительской галереи. Например, для Текстового ввода в галерее свойство OnChange может иметь значение:

Patch(GalleryData, ThisItem, {Name: TextInput.Text})

Обычно это нормально. Большинство элементов управления вызывают OnChange только когда пользователи напрямую изменяют их значение. Однако следующие элементы управления могут вызвать проблемы, так как они также активируются OnChange при изменении значения системы :

Например, при изменении ComboBox.DefaultSelectedItems срабатывает OnChange. Рассмотрим поле со списком в галерее с DefaultSelectedItems, установленным на First(ThisItem.A) и его свойством OnChange, имеющим значение:

UpdateIf(GalleryData, Name = ThisItem.Name, {
    A: Table({
        B: First(Self.SelectedItems).B
    })
})

Это выражение обновляет запись в источнике данных коллекции, которая соответствует имени текущего элемента, заменив A столбец новой таблицей.

Это вызывает бесконечный цикл. Когда пользователь изменяет значение в поле со списком, срабатывает OnChange, которое обновляет GalleryData, а это изменяет DefaultSelectedItems (поскольку First(ThisItem.A) ссылается на новую таблицу), что снова запускает OnChange, и так далее.

Чтобы избежать бесконечных циклов, используйте современные элементы управления или другие элементы управления, которые не активируются OnChange при изменении данных.

Низкая производительность из-за исправлений элементов

Даже если вы избегаете нежелательных циклов, исправление или обновление элементов коллекции может быть медленным, если коллекция содержит много элементов. Gallery не просто обновляет строки, связанные с изменёнными записями, — в некоторых случаях он перезагружает все элементы. Это происходит из-за слабо структурированного характера источников данных, что делает его трудным для коллекции , чтобы определить, изменилась ли одна запись или весь источник данных.

Gallery.Selected может неожиданно измениться

Свойство Selected в галерее является движущейся целью. Он может изменяться без взаимодействия с пользователем при возникновении любого из следующих действий:

  • Изменения Gallery.Default
  • Изменения Gallery.Items
  • Источники данных обновляются или актуализируются

Если требуется стабильная копия выбранного пользователем элемента, сохраните его в переменной. Например, задайте свойству ГалереяOnSelect значение:

Set(CurrentItem, Self.Selected)

Затем используйте CurrentItem в другом месте приложения, чтобы ссылаться на последний элемент, выбранный пользователем, а не на обновленное системой свойство Selected .

Не используйте Gallery.Selected в событии дочернего элемента управления

Свойство Selected в галерее изменяется, когда пользователь выбирает элемент. Однако это событие не синхронизировано с событиями дочернего элемента управления. Обращение к Gallery.Selected в событиях дочернего элемента управления может привести к неожиданным результатам.

Например, когда пользователь выбирает Checkbox в галерее, следующие события происходят в неопределенном порядке:

  • Checkbox.OnSelect
  • Checkbox.OnCheck
  • Gallery.Selected изменения в только что выбранной строке

Так как порядок этих событий не исправлен, использование Gallery.SelectedCheckbox.OnSelect может по-прежнему ссылаться на ранее выбранную строку.

Чтобы избежать проблем со временем, не используйте Gallery.Selected в событиях дочерних элементов управления. Если необходимо реагировать на изменения Gallery.Selected, используйте событие OnSelect самой галереи.

Присвоение Gallery.Items значения переменной или результата работы компонента Canvas может привести к непредвиденным результатам, в зависимости от того, когда этой переменной присваивается значение или когда она изменяется.

Коллекции должны знать схему своих элементов при загрузке приложения. Схема (также называемая фигурой) определяет имя и тип столбцов в источнике данных. Например, эта таблица:

[{A: "abc", B: 123}, {A: "def", B: 456}]

имеет схему с текстовым столбцом A и номерным столбцом B.

В большинстве случаев Галерея может определить схему на основе источника данных и выражений, используемых в приложении. Однако, если свойству Items присвоены выходные данные компонента Canvas или элемента управления Import, Gallery не может определить свою схему при загрузке, поэтому выходная таблица может быть еще недоступна, а схема может измениться. Галерея не будет отображать какие-либо элементы, если ему не известна его схема.

Эта же проблема может возникать, когда элементы имеют переменную, которая не инициализирована при загрузке приложения.

В качестве обходного решения укажите элементу Gallery ожидаемую схему с помощью переменной. Установите App.OnStart в:

If(false, Set(GalleryData, [{A: "abc", B: 123}]), Set(GalleryData, []))

Это позволяет системе определить схему GalleryData. Задайте для свойства Items элемента Gallery значение GalleryData, а затем при необходимости обновите его, указав фактический источник данных.

Не нужно думать, что AllItems содержит все элементы из набора данных

Свойство AllItems содержит элементы, загруженные в видимую область коллекции, не все элементы в Items. AllItems может измениться по мере прокрутки пользователя для загрузки дополнительных элементов. Как правило, это свойство используется для доступа к значениям дочерних элементов управления, с которым пользователь взаимодействует в настоящее время, что гарантирует загрузку этих элементов.

Не ссылайтесь на элемент в AllItems , если вы не уверены, прокрутил ли пользователь этот элемент.

Аналогичным образом AllItemsCount — это количество элементов, загруженных в представление, а не общее количество записей в элементах. Чтобы получить общее количество записей в элементах, используйте CountRows(<expression used for Items property>).

Следующие шаги