Почему при выборе строки в динамическом списке 1С она сдвигается в центр и как это отключить?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При работе в тонком клиенте «1С:Предприятие 8.3» пользователь может столкнуться с неприятным поведением интерфейса: если прокрутить динамический список вниз и щелкнуть левой кнопкой мыши по нужной строке (или вызвать контекстное меню), список неожиданно сдвигается, устанавливая выделенную строку точно по центру видимой области. В результате клик или контекстное меню срабатывают не для того элемента, на который наводил курсор пользователь. В этой статье мы проанализируем причины такого поведения платформы и разберем способы его устранения.

Причина самопозиционирования строки в списке

Выясним, почему происходит сдвиг таблицы. В платформе «1С:Предприятие 8.3» динамический список загружает данные с сервера порциями (страницами), а не целиком. Клиентское приложение не хранит точные координаты всех записей таблицы.

Сдвиг и центрирование строки происходят в момент, когда смена выделенного элемента провоцирует контекстный серверный вызов. Например, если в форме реализован обработчик события ПриАктивизацииСтроки, который обращается к серверу с передачей контекста формы (&НаСервере), платформа выполняет синхронизацию состояния клиента и сервера.

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

Как решить проблему и избежать сдвига строк

Штатной настройки или свойства в палитре свойств формы для отключения центрирования строки в платформе не предусмотрено. Однако можно устранить причины, вызывающие повторную синхронизацию и перезапрос порции данных.

Рассмотрим по шагам основные способы решения этой проблемы:

  1. Исключение контекстных серверных вызовов при навигации:

    Проанализируем код формы и найдем событие ПриАктивизацииСтроки таблицы. Если в нем содержится процедура с директивой &НаСервере, то при каждом клике мышью происходит контекстный вызов. Перенесите логику в вызовы &НаСервереБезКонтекста или используйте обработчик ожидания ПодключитьОбработчикОжидания. Это позволит отложить серверный вызов при быстрой перекрутке списка и предотвратит мгновенный сдвиг экрана.

  2. Настройка основной таблицы и уникальных ключевых полей:

    Убедитесь, что у реквизита формы с типом ДинамическийСписок заполнено свойство ОсновнаяТаблица. В списках с произвольными запросами задайте КлючевыеПоля, чтобы платформа могла однозначно идентифицировать строки и не теряла позиционирование при синхронизации страниц.

  3. Настройка гарантированной уникальной сортировки:

    Если в динамическом списке используется неуникальная сортировка (например, только по дате или наименованию), платформа при обновлении порции данных не может жестко зафиксировать порядок элементов. Добавьте в правила сортировки уникальное поле, например Ссылка.

  4. Отказ от вызова метода Обновить() при клике:

    Избегайте вызова метода Обновить() динамического списка внутри интерактивных событий выбора строки. Данный метод сбрасывает кэш подгруженных страниц и заново перерисовывает таблицу, что приводит к центрированию текущей строки.

  5. Оптимизация настройки контекстного меню:

    Если состав или доступность команд контекстного меню меняется в зависимости от выделенной строки, выполняйте изменение свойств элементов на клиенте без обращения к серверу.

Рассмотрим пример того, как правильно вынести логику из события ПриАктивизацииСтроки с помощью обработчика ожидания:


&НаКлиенте
Процедура СписокПриАктивизацииСтроки(Элемент)
    // Отключаем предыдущий вызов, если пользователь быстро листает список
    ОтключитьОбработчикОжидания("ОбновитьСопутствующиеДанные");
    // Запускаем обновление с задержкой в 0.3 секунды
    ПодключитьОбработчикОжидания("ОбновитьСопутствующиеДанные", 0.3, Истина);
КонецПроцедуры

&НаКлиенте
Процедура ОбновитьСопутствующиеДанные()
    ТекущиеДанные = Элементы.Список.ТекущиеДанные;
    Если ТекущиеДанные <> Неопределено Тогда
        ПолучитьДанныеНаСервере(ТекущиеДанные.Ссылка);
    КонецЕсли;
КонецПроцедуры

Применение описанных подходов позволяет исключить неожиданный сдвиг строк динамического списка при интерактивной работе пользователя.

← На главную