Delphi 在运行时添加附带的TColorListBox.Style颜色组,而不覆盖任何现有的自定义颜色?

Delphi 在运行时添加附带的TColorListBox.Style颜色组,而不覆盖任何现有的自定义颜色?,delphi,delphi-10.4-sydney,tcolor,Delphi,Delphi 10.4 Sydney,Tcolor,我在Delphi 10.4.2 32位VCL应用程序中有一个TColorListBox: object ColorListBox1: TColorListBox Left = 0 Top = 232 Width = 498 Height = 224 Align = alBottom Selected = clScrollBar Style = [cbCustomColors] ItemHeight = 20 TabOrder = 1 ExplicitWid

我在Delphi 10.4.2 32位VCL应用程序中有一个
TColorListBox

object ColorListBox1: TColorListBox
  Left = 0
  Top = 232
  Width = 498
  Height = 224
  Align = alBottom
  Selected = clScrollBar
  Style = [cbCustomColors]
  ItemHeight = 20
  TabOrder = 1
  ExplicitWidth = 484
end
TColorDialog
的帮助下,我在颜色列表中添加了一些自定义颜色项:

procedure TForm1.btnAddClick(Sender: TObject);
begin
  if dlgColor1.Execute(Self.Handle) then
  begin
    // insert on top:
    ColorListBox1.Items.InsertObject(0, 'My Color', TObject(dlgColor1.Color));
  end;
end;
……因此:

现在,我尝试添加其中一个包含的
t颜色列表框.Style
颜色组,而不覆盖以前添加的自定义颜色

procedure TForm1.btnAddGroupClick(Sender: TObject);
begin
  ColorListBox1.Style := ColorListBox1.Style + [cbStandardColors];
end;
但这会覆盖以前添加的自定义颜色

如何在运行时添加包含的
TColorListBox.Style
颜色组,而不覆盖任何现有的自定义颜色


(请注意,“cbCustomColors”默认包括:
Style=[cbCustomColors]

您必须将现有颜色保存在临时列表中:

procedure TForm1.btnAddGroupClick(Sender: TObject);
var
  CL: TStringList;
begin
  CL := TStringList.Create;
  try
    CL.Assign(ColorListBox1.Items); // save existing colors in a temporary list
    ColorListBox1.Style := ColorListBox1.Style + [cbStandardColors];
    ColorListBox1.Items.AddStrings(CL); // now add the temporary list
  finally
    CL.Free;
  end;
end;

如果要将现有颜色保留在列表顶部,则必须逐个插入临时颜色:

procedure TForm1.btnAddGroupClick(Sender: TObject);
begin
  if not (cbStandardColors in ColorListBox1.Style) then
    AddColorGroup([cbStandardColors]);
end;

procedure TForm1.AddColorGroup(AColorGroup: TColorBoxStyle);
var
  CL: TStringList;
  i: Integer;
begin
  CL := TStringList.Create;
  try
    CL.Assign(ColorListBox1.Items); // save existing colors in a temporary list
    ColorListBox1.Items.BeginUpdate;
    try
      ColorListBox1.Style := ColorListBox1.Style + AColorGroup;
      // keep existing colors on top:
      for i := CL.Count - 1 downto 0 do // insert temporary colors back one by one
        ColorListBox1.Items.InsertObject(0, CL[i], CL.Objects[i]);
    finally
      ColorListBox1.Items.EndUpdate;
    end;
  finally
    CL.Free;
  end;
end;