Добрый день!

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

Когда по логике происходит изменение свойства, то все кнопки, которые стоят справа "передергиваются", что выглядит некрасиво.

Пробовал испольтзовать BeginUpdate() / EndUpdate() у самой кнопки, у frmButtons, у самого грида, у формы в которой встроен грид - ничего не помогает...

Подскажите пожалуйста, как правильно заставить форму / контейнер прекратить отрисовываться пока меняется свойство элемента?

Нравится

2 комментария

Насколько знаю, между 3.3.2 и 3.4.0 был существенно переписан графический движок. Не факт, что получится что-то исправить без обновления версии.

Здравствуйте.

Попробуйте лочить (т.е. BeginUpdate/EndUpdate) окно (window), и при этом убедитесь, что других локов в этот момент не происходит. Иначе Ваше окно будет автоматически разлочено, что связано с особенностью в 3.3.2.
В 3.4.0 можно "лочить" и отдельные фреймы:

http://www.community.terrasoft.ru/blogs/7103

Показать все комментарии

Речь пойдет о разных, новых механизмах ядра 3.4

1. Производительный BeginUpdate/EndUpdate

В разработке UI (User Interface) многое зависит от того, какое расположение элементов управления, цвета, подсветки и т.д. Но, также много зависит от того, что видит пользователь при динамическом изменении карточки, конролов, окна при определенных действиях. Поэтому, всегда нужно уделять внимание тому, что пользователь визуально видеть не должен. Существуют механизмы скрытия рисования при динамическом изменении содержимого. Итак, постараюсь описать существующий механизм BeginUpdate/EndUpdate в Terrasoft 3.4.x.

В Terrasoft 3.4.x+ реализовано 2 возможности запретить окну обновлять содержимое:

  • «Глобальный» Lock (далее GlobalLock). Данный метод запретит Вам обновлять все окно (используется в Terrasoft 3.3.x)
  • «Индивидуальный» Lock (далее ControlLock). Этот метод запретит обновлять только тот контрол (и все его содержимое), которому был установлен Lock

В чем же разница и как понять, какой метод использовать? Для начала немного теории. GlobalLock – это функция, написанная Microsoft на все случаи жизни еще в Windows 2000. Она, конечно же, имеет право на жизнь, но с одним НО – только одно окно в системе может быть заблокировано в одну единицу времени. Блокировка любого другого окна (даже не вашего) - приведет к автоматической разблокировке вашего окна. Что же делает ControlLock? Этот метод блокирует обновление окна до того момента, пока вы лично не скажете ему, что оно может обновляться. В каждом из этих методов есть свои плюсы и минусы. В Terrasoft 3.4.x GlobalLock используется только для окон (Window), а для всего остального используется ControlLock. Для того чтобы понять разницу какой метод и когда запускается, рассмотрим пример:

/*Припустим, что у нас имеется FrameGroup’а, в которую динамически добавляются контролы.
Поэтому, на время добавления Нам нужно запретить окну обновляться*/

function wnd_WindowOnPrepare(Window) {
        Window.BeginUpdate(); /*Будет использован GlobalLock, так как это Window*/
        CreateControls();
        Window.EndUpdate();
}
function wnd_WindowOnPrepare(Window) {
        Self.BeginUpdate(); /*Будет использован GlobalLock, так как Self всегда является окном*/
        CreateControls();
        Self.EndUpdate();
}
function wnd_WindowOnPrepare(Window) {
        FrameGroup.BeginUpdate(); /*Будет использован ControlLock*/
        CreateControls();
        FrameGroup.EndUpdate();
}

Разница заключается в том, что в первом случае обновится все окно, а во втором – только FrameGroup’а. Отсюда следует, что использовать ControlLock производительнее, нежели GlobalLock. Но, использование GlobalLock также нужно, оно используется для окон, размеры которых вы хотите изменить, или же изменить содержимое самого окна. При этом комбинированное использование разрешено. Эти методы не конфликтуют друг с другом. Рассмотрим пример:
Пример
function Lock() {
        Window.BeginUpdate();
        FrameSet.BeginUpdate(); /*FrameSet заблокирован*/
        Frame.BeginUpdate(); /*заблокировали Frame*/
        Window.EndUpdate(); /*на этом этапе окно обновит элементы управления, кроме Framе’a, FrameSet’а и их содержимого*/
        FrameSet.EndUpdate(); /*Обновится FrameSet, но Frame по прежнему заблокирован, а значит и его содержимое также не обновится*/
        Frame.EndUpdate(); /*Теперь Frame обновится*/
}

Также, в связи со спецификой GlobalLock – ведется счетчик блоков. Т.е. сколько раз был вызван BeginUpdate(), то столько же нужно вызвать и EndUpdate(). А вот при ControlLock такой счетчик отсутствут, достаточно один раз вызвать EndUpdate().
Итого:
  • GlobalLock. Используйте для окна, размеры которого меняются или меняется непосредственно его содержимое
  • ControlLock. Используйте для конкретного Frame’а/FrameGroup’ы и т.д. внутри которого будут происходить изменения

2. Button + Image
Button – один из самых используемых элементов управления. Без него практически не существует ни одного окна. Поэтому этот элемент управления просто обязан иметь какие-то дополнительные возможности для дизайна.
В Terrasoft 3.4.x добавлена возможность установить Image для Button’а. Причем, чтобы добавить изображение нужно только указать ImageList и указать имена для изображения (Normal, Hot, Pressed и Disabled). Также, изображение можно позиционировать с разных сторон от текста. Индивидуально хочется еще добавить, что, в отличие от Terrasoft 3.3.x, Button может быть любого размера (с выключенным AutoSize). Также, размеры можно ограничить минимальными значениями. Форматы изображения: *.ico, *.bmp, *.jpg, *.png (в принципе все, которые можно добавить в ImageList)
Button

3. Label. Выравнивание текста
При дизайне карточки или окна, иногда нужно сделать некий косметический момент с помощью Label. Но в то же время при его использовании испытывались некоторые трудности: как выровнять текст внутри Label’а? Эта проблема была решена в версии 3.4.1.14+. К свойствам Label была добавлена возможность позиционирования текста
Label

4. Настройка шрифтов
Наверное, каждый разработчик сталкивается с задачей настройки шрифтов: сделать Label большим шрифтом, изменить цвет фона контрола и т.д. До этого момента изменить шрифт и цвет можно было только во время выполнения (например, на OnPrepare). Для решения этого вопроса, начиная с версии Terrasoft 3.4.1.14+, были добавлены свойства, позволяющие в TSAdmin настроить шрифты и цвета. Что же можем делать?:

  1. Можем изменять шрифт и цвет Caption’а:
  2. CaptionFont

  3. Можем изменить шрифт и цвет текста
  4. TextFont

  5. Можем изменять цвет фона
  6. backgroundColor

Но, кроме элементов управления есть контролы, которые используются для группировки (FrameSet, Frame и FrameGroup). Для них также есть возможность настройки шрифтов
LayoutFont

Вот, собственно, часть того, что нового для разработки UI в Terrasoft 3.4.x я хотел рассказать.
Приятной разработки!

P.S. Напомню, что и в каких версия появилось (появится):

  • механизм BeginUpdate/EndUpdate работает во всех версиях 3.4.х;
  • возможность добавления изображения к Button – 3.4.0.x;
  • возможность позиционирования текста в Label – 3.4.1.14+;
  • возможность настройки шрифтов – 3.4.1.14+

Нравится

Поделиться

2 комментария

Спасибо, полезная информация.

А если в сервисах использовать позиционирование и шрифты и запустить на бинарниках 3.4.0 - будет валиться или просто игнорировать?

Если запустить на бинарниках 3.4.0, то будет просто игнорироваться

Показать все комментарии
Публикация

Хочу рассказать об использовании BeginUpdate/EndUpdate в версии 3.4.0. В предыдущих версиях Terrasoft 3.x использовался Lock для окна, который Microsoft реализовал так, что в один и тот же момент в системе может быть «залочено» только одно окно. Это, иногда, приводило к неприятным вещям. Начиная с версии 3.4.0 использование функций BeginUpdate/EndUpdate было разделено:
1. Окна (Window) используют стандартную логику Windows для глобального Lock’а окна
2. Frame, FrameSet, FrameGroup и остальные объекты, которые имеют функции BeginUpdate/EndUpdate, используют собственную функцию Lock’а, которая превосходит по производительности глобальный Lock
Таким образом, если у Вас что-либо меняется во Frame’е или FrameGroup’е, то достаточно «залочить» только их.

В чем же производительность? Как минимум в том, что глобальный Lock при UnLock’е обновляет все окно, независимо от того что в нем поменялось, а Lock для конкретного объекта будет обновлять только его содержимое. Плюс ко всему, если у Вас «залочено» окно с помощью глобального Lock’a, то при каком-либо другом Lock’е в системе, оно будет автоматически «разлочено», чего не произойдет, если «лочить» только нужные объекты

Нравится

Поделиться

2 комментария

Прикольно. Артем, а ведется ли счетчик этих локов? Просто помню в 3.3.2 было такое, что если ты делаешь несколько BeginUpdate() подряд, то столько же должен сделать и EndUpdate(), чтобы окно разлочить.

Счетчик не ведется, достаточно сделать один раз EndUpdate() и объект разлочится, но все же в скриптах должен быть порядок: BeginUpdate == EndUpdate :smile:

Показать все комментарии