Сумма подэлементов в TListView

Как мы можем суммировать некоторые SubItems в TListView? Если вы посмотрите на картинку ниже,

введите описание изображения здесь

Сначала заполняем Col 1 до Col 4 для Group1 и Group2. Проблема в том, как мы можем суммировать Подэлементы Col 2 и поместить результат в Col 3. Картинка, которую я публикую выше, ясна, но если я хочу объяснить, как суммировать, это как бы вы суммируете текущий SubItem ListView с указанным выше SubItem. И для первого SubItem в каждой группе мы указываем тот же номер, например Col 2.


person return    schedule 07.12.2012    source источник
comment
Вы можете просто сложить числа, используя оператор +. Если вы можете заполнить древовидное представление, то наверняка сможете добавлять числа по мере продвижения.   -  person David Heffernan    schedule 07.12.2012


Ответы (1)


Что-то вроде этого может сделать то, что вы хотите:

procedure TForm1.Button1Click(Sender: TObject);
var
  I: Integer;
  Value: Integer;
  GroupID: Integer;
  GroupSum: Integer;
begin
  GroupID := 0;
  GroupSum := 0;
  for I := 0 to ListView1.Items.Count - 1 do
  begin
    if Assigned(ListView1.Items[I].SubItems) and
      (ListView1.Items[I].SubItems.Count > 0) and
      TryStrToInt(ListView1.Items[I].SubItems[0], Value) then
    begin
      if GroupID <> ListView1.Items[I].GroupID then
      begin
        GroupSum := 0;
        GroupID := ListView1.Items[I].GroupID;
      end;
      GroupSum := GroupSum + Value;
      if ListView1.Items[I].SubItems.Count < 2 then
        ListView1.Items[I].SubItems.Add(IntToStr(GroupSum))
      else
        ListView1.Items[I].SubItems[1] := IntToStr(GroupSum);
    end;
  end;
end;

Что ж, для тех, кто хочет смоделировать ситуацию OP, вот код (просто поместите компонент представления списка в форму и напишите обработчик события):

procedure TForm1.FormCreate(Sender: TObject);
var
  ListItem: TListItem;
  ListGroup: TListGroup;
  ListColumn: TListColumn;
begin
  ListView1.Clear;
  ListView1.GroupView := True;
  ListView1.ViewStyle := vsReport;

  ListColumn := ListView1.Columns.Add;
  ListColumn.Caption := 'Column 1';
  ListColumn.Width := 90;
  ListColumn := ListView1.Columns.Add;
  ListColumn.Caption := 'Column 2';
  ListColumn.Width := 90;
  ListColumn := ListView1.Columns.Add;
  ListColumn.Caption := 'Column 3';
  ListColumn.Width := 90;

  ListGroup := ListView1.Groups.Add;
  ListGroup.GroupID := 0;
  ListGroup.Header := 'Group 1';
  ListGroup := ListView1.Groups.Add;
  ListGroup.GroupID := 1;
  ListGroup.Header := 'Group 2';

  ListItem := ListView1.Items.Add;
  ListItem.GroupID := 0;
  ListItem.Caption := 'Item 1';
  ListItem.SubItems.Add('22');
  ListItem := ListView1.Items.Add;
  ListItem.GroupID := 0;
  ListItem.Caption := 'Item 2';
  ListItem.SubItems.Add('11');
  ListItem := ListView1.Items.Add;
  ListItem.GroupID := 1;
  ListItem.Caption := 'Item 3';
  ListItem.SubItems.Add('94');
  ListItem := ListView1.Items.Add;
  ListItem.GroupID := 1;
  ListItem.Caption := 'Item 4';
  ListItem.SubItems.Add('42');
  ListItem := ListView1.Items.Add;
  ListItem.GroupID := 1;
  ListItem.Caption := 'Item 5';
  ListItem.SubItems.Add('21');
end;
person TLama    schedule 07.12.2012
comment
Это упускает из виду тот факт, что, скорее всего, необработанные данные находятся в структуре данных с целыми значениями. В этом случае нет причин для StrToInt. Было бы глупо заполнять представление списка строками, забывать о базовых данных и затем пытаться их суммировать. - person David Heffernan; 07.12.2012
comment
@David, поскольку в вопросе отсутствует информация о том, использует ли OP представление списка в виртуальном режиме или нет, я использовал этот способ. Если это глупо или нет, мне все равно, важная часть в этом случае - это сохранение групповой суммы, которая не упоминается в вашем любимом комментарии. - person TLama; 07.12.2012
comment
Что ж, это подразумевается в этом комментарии. Но даже если предположить, что список не виртуальный, за этим должна быть какая-то структура данных. И должен быть какой-то код для заполнения списка на основе содержимого этой структуры данных. И именно в тот момент, когда заполняется представление списка, следует произвести суммирование. И вот как вы можете быть уверены, что используете только IntToStr и никогда не должны использовать StrToInt. Вы понимаете, о чем я? - person David Heffernan; 07.12.2012
comment
@ Дэвид, теперь я понимаю, что ты имеешь в виду. Да, это так. Просто чтобы добавить, когда появится способ изменить эти значения, вам придется пересчитать суммы в группе, к которой принадлежит подпункт edited для элементов, начиная с edited один до последнего элемента этой группы. - person TLama; 07.12.2012
comment
Конечно, если вы начнете редактировать эти данные, все станет сложнее. Но в этот момент вы наверняка отразите правки обратно в исходные данные, и тогда моя точка зрения останется в силе. Или вы делаете все это виртуально, и применимы те же аргументы. В любом случае, вы хорошо ответили на вопрос, который стоял перед вами, поэтому я проголосовал за. - person David Heffernan; 07.12.2012