При работе в тонком клиенте «1С:Предприятие 8.3» пользователь может столкнуться с неприятным поведением интерфейса: если прокрутить динамический список вниз и щелкнуть левой кнопкой мыши по нужной строке (или вызвать контекстное меню), список неожиданно сдвигается, устанавливая выделенную строку точно по центру видимой области. В результате клик или контекстное меню срабатывают не для того элемента, на который наводил курсор пользователь. В этой статье мы проанализируем причины такого поведения платформы и разберем способы его устранения.
Выясним, почему происходит сдвиг таблицы. В платформе «1С:Предприятие 8.3» динамический список загружает данные с сервера порциями (страницами), а не целиком. Клиентское приложение не хранит точные координаты всех записей таблицы.
Сдвиг и центрирование строки происходят в момент, когда смена выделенного элемента провоцирует контекстный серверный вызов. Например, если в форме реализован обработчик события ПриАктивизацииСтроки, который обращается к серверу с передачей контекста формы (&НаСервере), платформа выполняет синхронизацию состояния клиента и сервера.
Во время такой синхронизации клиент перезапрашивает у сервера порцию данных, отсчитываемую от выбранной строки. При загрузке этой порции платформенный механизм отображения таблиц принудительно позиционирует текущую строку по центру таблицы.
Штатной настройки или свойства в палитре свойств формы для отключения центрирования строки в платформе не предусмотрено. Однако можно устранить причины, вызывающие повторную синхронизацию и перезапрос порции данных.
Рассмотрим по шагам основные способы решения этой проблемы:
Проанализируем код формы и найдем событие ПриАктивизацииСтроки таблицы. Если в нем содержится процедура с директивой &НаСервере, то при каждом клике мышью происходит контекстный вызов. Перенесите логику в вызовы &НаСервереБезКонтекста или используйте обработчик ожидания ПодключитьОбработчикОжидания. Это позволит отложить серверный вызов при быстрой перекрутке списка и предотвратит мгновенный сдвиг экрана.
Убедитесь, что у реквизита формы с типом ДинамическийСписок заполнено свойство ОсновнаяТаблица. В списках с произвольными запросами задайте КлючевыеПоля, чтобы платформа могла однозначно идентифицировать строки и не теряла позиционирование при синхронизации страниц.
Если в динамическом списке используется неуникальная сортировка (например, только по дате или наименованию), платформа при обновлении порции данных не может жестко зафиксировать порядок элементов. Добавьте в правила сортировки уникальное поле, например Ссылка.
Избегайте вызова метода Обновить() динамического списка внутри интерактивных событий выбора строки. Данный метод сбрасывает кэш подгруженных страниц и заново перерисовывает таблицу, что приводит к центрированию текущей строки.
Если состав или доступность команд контекстного меню меняется в зависимости от выделенной строки, выполняйте изменение свойств элементов на клиенте без обращения к серверу.
Рассмотрим пример того, как правильно вынести логику из события ПриАктивизацииСтроки с помощью обработчика ожидания:
&НаКлиенте
Процедура СписокПриАктивизацииСтроки(Элемент)
// Отключаем предыдущий вызов, если пользователь быстро листает список
ОтключитьОбработчикОжидания("ОбновитьСопутствующиеДанные");
// Запускаем обновление с задержкой в 0.3 секунды
ПодключитьОбработчикОжидания("ОбновитьСопутствующиеДанные", 0.3, Истина);
КонецПроцедуры
&НаКлиенте
Процедура ОбновитьСопутствующиеДанные()
ТекущиеДанные = Элементы.Список.ТекущиеДанные;
Если ТекущиеДанные <> Неопределено Тогда
ПолучитьДанныеНаСервере(ТекущиеДанные.Ссылка);
КонецЕсли;
КонецПроцедуры
Применение описанных подходов позволяет исключить неожиданный сдвиг строк динамического списка при интерактивной работе пользователя.