отключить строку в cxgrid

Мне нужна строка в cxgrid, где UserRights = 3 отключен.

Я попробовал это предложение, но, похоже, оно не работает:

// MAKING A ROW READ ONLY
procedure TForm1.cxGrid1DBTableView1InitEdit(
  Sender: TcxCustomGridTableView; AItem: TcxCustomGridTableItem;
  AEdit: TcxCustomEdit);
var
  AKeyValue : Variant;
begin
  AKeyValue := Sender.DataController.GetRecordId(Sender.Controller.FocusedRecordIndex);
  if (AKeyValue = '3') then
    AEdit.ActiveProperties.ReadOnly := True;
end;

Я хочу, чтобы пользователь мог редактировать данные, но не там, где UserRights=3.

Я также попытался заблокировать напрямую:

procedure TData_Module.USERSBeforePost(DataSet: TDataSet);
begin
if main_form.dxStatusBar1.Panels[0].Text = '3' then
Users.Post
else
showmessage('Access denied.');
abort;
end;

Это работает нормально, пока main_form.dxStatusBar1.Panels[3].Text не 3. Если это 3, и я пытаюсь изменить любую запись, я вылетаю из программы. Я думал, что лучше заблокировать редактирование строки, но, похоже, это не работает. Есть идеи ?


person user3351050    schedule 07.11.2016    source источник
comment
Я мало что знаю о db, но в вашей первой попытке вы, кажется, запрашиваете идентификатор записи, а не значение поля с именем UserRights.   -  person Tom Brunberg    schedule 07.11.2016
comment
Во второй попытке, если ...Panels[0].Text действительно отражает UserRights, у вас неправильная логика, возможно, вам следует использовать <> '3'. Кроме того, я думаю, что вы пропустили пару begin end вокруг двух строк после else.   -  person Tom Brunberg    schedule 07.11.2016


Ответы (2)


Обновление Код в событии EditInit связан с проблемами, описанными ниже. Следующий метод позволяет избежать этих проблем:

procedure TForm1.cxGrid1DBTableView1Editing(Sender: TcxCustomGridTableView;
    AItem: TcxCustomGridTableItem; var AAllow: Boolean);
var
  AKeyValue : Variant;
  ADataSet : TDataset;
begin
  ADataSet := cxGrid1DBTableView1.DataController.DataSource.DataSet;
  AKeyValue := ADataSet.FieldByName('ID').AsInteger;  //  or 'UserRights'
  if AKeyValue = '3' then
    AAllow := False;
end;

Обратите внимание, что вы должны использовать приведенный выше код вместо кода EditInit, а не так хорошо, как он.

Первоначальный вариант ответа:

Ответ, который вам дал пользователь 763539, правильный, поэтому +1 за это; если вы не установите KeyFieldNames DataController в поле, значение которого вы хотите проверить, AKeyValue возвращает Null.

Однако просто установка значения true для ReadOnly имеет эффект в графическом интерфейсе, который пользователь может счесть недружественным/сбивающим с толку, а именно: когда вы щелкаете в ячейке строки, которая доступна только для чтения, тем не менее значение в ячейке по-прежнему отображается как выбранное, что дает впечатление, что вы могли отредактировать его, пока не попытаетесь. Чтобы избежать этого, измените обработчик InitEdit, как показано ниже: вызов Abort предотвращает отображение выбранного значения ячейки.

procedure TForm1.cxGrid1DBTableView1InitEdit(Sender: TcxCustomGridTableView;
    AItem: TcxCustomGridTableItem; AEdit: TcxCustomEdit);
var
  AKeyValue : Variant;
begin
  AKeyValue := Sender.DataController.GetRecordId(Sender.Controller.FocusedRecordIndex);
  if (AKeyValue = '3') then begin
    AEdit.ActiveProperties.ReadOnly := True;
    Abort;
  end;
end;

Предупреждение: кажется, что в v.15 есть причуда, по крайней мере, в cxGrid, которая выставляется с использованием события InitEdit таким образом. У меня есть поле «Имя», содержимое которого просто 'Name ' + IntToStr(ID), где ID — это мой эквивалент прав пользователя OP. Следующее показывает эту причуду:

  1. Щелкните в любой строке данных, отличной от ID/UserRights = 3.
  2. Щелкните в строке 3;
  3. Теперь щелкните заголовок столбца Имя.

После шага 3 в ячейке Имя в строке ID/UserRights = 3 отображается значение строки, выбранной на шаге 1. Эту проблему нельзя избежать, задав для GridMode значение True. Кажется, это проблема, которая влияет только на отображение поля, а не на содержимое данных поля. Я назвал это «причудой», а не ошибкой, потому что я не уверен, что разработчики cxGrid когда-либо предполагали, что Abort будет вызываться внутри события InitEdit.

person MartynA    schedule 07.11.2016
comment
Однако, если я отсортирую записи в cxgrid (щелкнув заголовок столбца), то внезапно ранее заблокированная строка станет доступной для редактирования. Это ошибка? - person user3351050; 07.11.2016
comment
Кажется, я должен использовать «режим сетки», чтобы это работало правильно. :( - person user3351050; 07.11.2016

Вам нужно установить

DataController.KeyFieldNames GridView

к вашему имени поля.

person user763539    schedule 07.11.2016