user3351050
user3351050

Reputation: 368

disable a row in cxgrid

I want a row in cxgrid where UserRights = 3 disabled.

I tried this suggestion but it does not seem to work :

// 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;

I want the user to be able to edit data but not where UserRights=3.

I also tried blocking directly :

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

This works OK as long as the main_form.dxStatusBar1.Panels[3].Text is not 3. If it is 3 and I try and modify any record I crash the program. I thought that blocking the row from being edited is a better idea but it does not seem to work. Any ideas ?

Upvotes: 0

Views: 3697

Answers (2)

MartynA
MartynA

Reputation: 30745

Update The code in the EditInit event involves the problems described below. The following method avoids these problems:

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;

Note that you should use the above code instead of the EditInit code, not as well as it.

Original version of answer:

The answer you have been given by user763539 is correct, so +1 for that; if you don't set the DataController's KeyFieldNames to the field whose value you want to test, AKeyValue returns Null.

However, merely setting ReadOnly to true has an effect in the GUI that the user may find unfriendly/confusing, namely that when you click in a cell of the row which is ReadOnly, nevertheless the value in the cell is still displayed as selected, giving the impression that you could edit it, until you try. To avoid that, modify your InitEdit handler as shown below - the call to Abort prevents the cell value from being displayed selected.

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;

Warning: There seems to be a quirk in v.15 at least of the cxGrid which is exposed by using the InitEdit event in this way. I have a field 'Name' whose contents is simply 'Name ' + IntToStr(ID) where ID is my equivalent of the OP's UserRights. The following shows this quirk:

  1. Click in any data row other than the ID/UserRights = 3 one.
  2. Click in the 3 row;
  3. Now click the Name column header.

After step 3, the Name cell in the ID/UserRights = 3 row, displays the value of the row clicked in step 1. This problem isn't avoided by setting GridMode to True. It seems to be a problem which only affects the display of the field, not the field's data contents. I have called it a 'quirk' and not a bug, because I'm not sure the cxGrid's designers ever intended Abortto be called inside the InitEdit event.

Upvotes: 3

user763539
user763539

Reputation: 3719

You need to set

GridView's DataController.KeyFieldNames

to your fieldname.

Upvotes: 1

Related Questions