Блокировка формы и отдельных полей для изменения, условия, способы

Блокировка формы для изменений

Объект, открытый в режиме “Только чтение” (ReadOnly) не может быть изменен пользователем, данные, хранящиеся в объекте, будут доступны только для чтения.

Режим ReadOnly может понадобиться в разных ситуациях, к примеру:

  • Один пользователь открыл объект на редактирование, в это время другой пользователь пытается также открыть этот же объект на редактирование.
  • У пользователя нет прав изменять какое-либо поле объекта, или сам объект, но есть право просматривать данные.

Режим можно условно поделить на 3 составляющие:

  • Блокировка интерфейса пользователя
  • Блокировка объекта данных в памяти приложения
  • Блокировка объекта данных в базе данных

Блокировка интерфейса пользователя

Если пользователь не может вносить изменения в объект, он должен это осознавать в момент открытия формы редактирования. Если объект в данный момент недоступен из-за блокировки другим пользователем, рекомендуется вывести предупреждение типа “Объект заблокирован другим пользователем. Вы желаете открыть объект только на чтение? Да\Нет”. Если пользователь все же желает открыть объект в режиме ReadOnly, необходимо заблокировать контролы для редактирования полей объекта. Также необходимо скрыть кнопки Сохранить и Сохранить и закрыть (только для случая полной блокировки, а не блокировки отдельных полей объекта).

Для блокировки интерфейса пользователя в Windows-приложениях используется класс EditManager.

EditManager позволяет либо заблокировать объект полностью, либо заблокировать только некоторые его поля.

Важно: Стоит отметить, что EditManager блокирует только те поля объекта, которые зарегистрированы в нем.

  • Полная блокировка объекта через EditManager осуществляется установкой свойства
 EditManager.ReadOnly = true;
  • Частичная блокировка объекта (блокировка отдельных полей) осуществляется вызовом метода EditManager.SetReadonlyFlagProperties.

Блокировка объекта данных в памяти приложения

Блокировка объекта в памяти осуществляется вызовом метода объекта DataObject.LockObject(Key), где Key - некий ключ блокировки типа Guid. Разблокировать объект можно только этим ключом при помощи метода DataObject.UnLockObject(Key).

При вызове метода LockObject блокировка в базу не отправляется.

Пример можно посмотреть в статье Варианты открытия объекта только на чтение.

Блокировка объекта данных в базе данных

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

Блокировка объекта в базе данных железно защищает объект от изменений объекта другими пользователями. Создается запись в таблице STORMNETLOCKDATA и, пока она там существует, изменить объект может только пользователь, заблокировавший объект.

Пример можно посмотреть в статье Сервис блокировок.

Блокировка для изменения отдельных полей формы

Была поставлена следующая задача: “Сделать для разных приложений доступными разные поля для одной и той же формы”. Возможно следующее решение данной задачи:

  • В зависимости от того, какое приложение запущено, можно блокировать поля на редактирование с помощью EditManager.SetReadonlyFlagProperties.
  • Определять запущенное приложение можно при его запуске путём записи определённого значения в статическое поле общедоступного класса.

Для демонстрации варианта решения данной проблемы ниже представлено решение следующей задачи: “Есть список сотрудников. Сотрудники отдела кадров могут редактировать поля “ФИО”, “Дата рождения” и “Адрес прописки”, а руководители предприятия могут оценивать “Работоспособность” сотрудников”.

Работа в Flexberry Tool

В Flexberry была создана диаграмма классов.

Диаграмма классов

Затем определены приложения пользователей и сгенерирован программный код.

Работа с программным кодом

В общедоступном для разрабатываемых приложений классе определяем статическое поле.

    public enum tWorkerShowType //перечислимый тип для указания запущенного приложения
    {
        Unknown, //ничего не было установлено
        ToHead, //начальник
        ToPersonnelOffice //отдел кадров
    }
    public class Сотрудник : ICSSoft.STORMNET.DataObject
    {
        public static WorkerShowType CurShowType = tWorkerShowType.Unknown; //статическое поле для указания запущенного приложения
        //...
    }

В коде приложения определяем значение этого статического поля.

static void Main()
{
    try
    {
        Сотрудник.CurShowType = tWorkerShowType.ToPersonnelOffice; //определяем значение статического поля
        //...
    }
    //...
}

Переопределяем метод Edit на форме редактирования.

public override void Edit(ICSSoft.STORMNET.DataObject dataobject, string contpath, string propertyname, object tag)
{
  base.Edit(dataobject, contpath, propertyname, tag); //вызов базового метода
  if (dataobject != null)
    {
      switch (Сотрудник.CurShowType)
        {
          case tWorkerShowType.ToHead: //если запущено приложение руководителя
            EditManager.SetReadonlyFlagProperties(
            true, new string[] { "ФИО", "ДатаРождения", "АдресПрописки" });
            break;
          case tWorkerShowType.ToPersonnelOffice: //если запущено приложение сотрудника отдела кадров
            EditManager.SetReadonlyFlagProperties(true, new string[] { "Работоспособность" });
            break;
          case tWorkerShowType.Unknown: //если не определён тип приложения
            MessageBox.Show("Не был установлен параметр, от имени кого была запущена форма.");
            break;
        }
    }
}