Какое событие мне следует использовать?
Ни один из вышеперечисленных. Я думаю, вы ошибаетесь. Кажется, вы хотите автоматически обновлять поле TotalPrice при изменении поля Qty или UnitPrice. Самый продуктивный способ думать об этом - как об операции манипулирования данными, а не как об операции с графическим интерфейсом пользователя, и именно так вы должны ее кодировать.
CxGrid - это компонент, поддерживающий базу данных, и они закодированы для автоматического отражения изменений данных, поэтому способ обновления поля TotalPrice - это сделать это в коде, который работает с набором данных, НЕ strong > в коде, который работает с cxGrid. Если вы попытаетесь сделать это в коде для cxGrid, вы обнаружите, что постоянно «боретесь» с сеткой, потому что она знает, как быть осведомленной о БД, и вы, по сути, пытаетесь это разрушить.
Попробуйте приведенный ниже пример проекта. Настройте новый проект VCL, добавьте TClientDataSet, TDataSource и TDBNavigator и «подключите их» обычным способом.
Настройте обработчик событий OnCalcFields для CDS и событие FormCreate для формы, а затем добавьте код, показанный ниже.
Когда проект запускается, он динамически создает cxGRid для отображения данных (я сделал это таким образом, потому что в cxGrid так много настроек и подкомпонентов, что проще всего создать их в коде, а не указывать его настройки в ответе вроде это).
Поиграйте с изменением значений в полях Qty и UnitPrice и обратите внимание, что TotalPrice обновляется автоматически, не требуя никакого кода, который работает с cxGrid.
type
TForm1 = class(TForm)
CDS1: TClientDataSet;
DS1: TDataSource;
DBNavigator1: TDBNavigator;
procedure FormCreate(Sender: TObject);
procedure CDS1CalcFields(DataSet: TDataSet);
private
public
cxGrid : TcxGrid;
cxLevel : TcxGridLevel;
cxView : TcxGridDBTableView;
end;
[...]
// This is a utility function to create TFields in code
function CreateField(AFieldClass : TFieldClass; AOwner : TComponent; ADataSet : TDataSet;
AFieldName, AName : String; ASize : Integer; AFieldKind : TFieldKind) : TField;
begin
Result := AFieldClass.Create(AOwner);
Result.FieldKind := AFieldKind;
Result.FieldName := AFieldName;
Result.Name := AName;
Result.Size := ASize;
Result.DataSet := ADataSet;
end;
procedure TForm1.FormCreate(Sender: TObject);
var
i : Integer;
Field : TField;
Col : TcxGridDBColumn;
begin
// First, create the Fields of the ClientDataSet
Field := CreateField(TIntegerField, Self, CDS1, 'ID', 'CDS1ID', 0, fkData);
Field := CreateField(TIntegerField, Self, CDS1, 'Qty', 'CDS1Qty', 0, fkData);
Field := CreateField(TCurrencyField, Self, CDS1, 'UnitPrice', 'CDS1UnitPrice', 0, fkData);
Field := CreateField(TCurrencyField, Self, CDS1, 'TotalPrice', 'CDS1TotalPrice', 0, fkInternalCalc);
// Field.ReadOnly := True;
CDS1.CreateDataSet;
CDS1.IndexFieldNames := 'ID';
// Next, populate the CDS with a few records
// Note : If we are using calculated fields, we do to need to specify
// a value for the TotalPriced field
CDS1.InsertRecord([1, 1, 1]);
CDS1.InsertRecord([2, 2, 5]);
CDS1.InsertRecord([3, 3, 6]);
CDS1.First;
// Now, create a cxGrid to display the CDS data
cxGrid := TcxGrid.Create(Self);
cxGrid.Parent := Self;
cxGrid.Width := 400;
cxLevel := cxGrid.Levels.Add;
cxLevel.Name := 'Firstlevel';
cxView := cxGrid.CreateView(TcxGridDBTableView) as TcxGridDBTableView;
cxView.Name := 'ATableView';
cxView.DataController.KeyFieldNames := 'ID';
cxView.DataController.Options := cxView.DataController.Options + [dcoImmediatePost];
cxLevel.GridView := cxView;
cxView.DataController.DataSource := DS1;
cxView.DataController.CreateAllItems;
// Since the TotalPrice column is a calculated field, we need to
// prevent the user from attempting to edit it
Col := cxView.GetColumnByFieldName('TotalPrice');
Col.Options.Editing := False;
ActiveControl := cxGrid;
end;
// Procedure to calculate the TotalPrice field
procedure CalculateTotalPrice(DataSet : TDataSet);
var
Qty : Integer;
UnitPrice,
TotalPrice : Currency;
begin
Qty := DataSet.FieldByName('Qty').AsInteger;
UnitPrice := DataSet.FieldByName('UnitPrice').AsCurrency;
TotalPrice := Qty * UnitPrice;
DataSet.FieldByName('TotalPrice').AsCurrency := TotalPrice;
end;
procedure TForm1.CDS1CalcFields(DataSet: TDataSet);
begin
CalculateTotalPrice(DataSet);
end;
person
MartynA
schedule
09.10.2018