Блокировка формы для изменений
Объект, открытый в режиме “Только чтение” (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;
}
}
}
base.Edit(...)
должен предшествовать определению полей, доступных для редактирования.