【问题标题】:Changing color for specific items in a listbox [duplicate]更改列表框中特定项目的颜色 [重复]
【发布时间】:2021-06-23 08:55:30
【问题描述】:

我正在创建一个消息传递应用程序,我想在列表框中进行聊天(聊天的选择),并且我想在有人在线时将名称更改为绿色。有没有办法做到这一点?

【问题讨论】:

标签: delphi listbox vcl


【解决方案1】:

这很容易。您只需要所有者绘制列表框。

将列表框的Style 设置为lbVirtualOwnerDraw 并分配其OnDataOnDrawItem 处理程序:

unit ChatMainForm;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics,
  Controls, Forms, Dialogs, StdCtrls, Generics.Collections;

type
  TUserData = record
    UserName: string;
    Online: Boolean;
  end;

  TMainForm = class(TForm)
    lbUsers: TListBox;
    procedure lbUsersData(Control: TWinControl; Index: Integer;
      var Data: string);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure lbUsersDrawItem(Control: TWinControl; Index: Integer; Rect: TRect;
      State: TOwnerDrawState);
  private
    FUserData: TList<TUserData>;
  public

  end;

var
  MainForm: TMainForm;

implementation

uses
  Math;

{$R *.dfm}

procedure TMainForm.FormCreate(Sender: TObject);

  function usr(const AUserName: string; AOnline: Boolean): TUserData;
  begin
    Result.UserName := AUserName;
    Result.Online := AOnline;
  end;

begin

  FUserData := TList<TUserData>.Create;
  FUserData.Add(usr('Andreas Rejbrand', True));
  FUserData.Add(usr('John Doe', False));
  FUserData.Add(usr('Mary Smith', True));
  FUserData.Add(usr('Bill Evans', False));
  FUserData.Add(usr('Jonathan Stone', True));
  FUserData.Add(usr('Gary Jones', True));

  lbUsers.Count := FUserData.Count;

end;

procedure TMainForm.FormDestroy(Sender: TObject);
begin
  FUserData.Free;
end;

procedure TMainForm.lbUsersData(Control: TWinControl; Index: Integer;
  var Data: string);
begin
  if InRange(Index, 0, FUserData.Count - 1) then
    Data := FUserData[Index].UserName;
end;

procedure TMainForm.lbUsersDrawItem(Control: TWinControl; Index: Integer;
  Rect: TRect; State: TOwnerDrawState);
const
  BackColors: array[Boolean] of TColor = (clWindow, clWindow);
  TextColors: array[Boolean] of TColor = (clGrayText, clWindowText);
begin
  if InRange(Index, 0, FUserData.Count - 1) then
  begin
    lbUsers.Canvas.Brush.Color := BackColors[FUserData[Index].Online];
    lbUsers.Canvas.Font.Color := TextColors[FUserData[Index].Online];
    if odSelected in State then
    begin
      lbUsers.Canvas.Brush.Color := clHighlight;
      lbUsers.Canvas.Font.Color := clHighlightText;
    end;
    lbUsers.Canvas.Font.Style := [];
    if FUserData[Index].Online then
      lbUsers.Canvas.Font.Style := [fsBold];
    lbUsers.Canvas.FillRect(Rect);
    InflateRect(Rect, -2, -2);
    var S := FUserData[Index].UserName;
    lbUsers.Canvas.TextRect(Rect, S,
      [tfSingleLine, tfVerticalCenter, tfEndEllipsis]);
  end;
end;

end.

结果:

显然,您需要稍微调整一下代码以使其看起来不错,但至少这应该会给您一个良好的开端。

【讨论】:

  • 第一个练习:不要总是使用白色背景,而是将“在线”背景改为clLime。 ?
猜你喜欢
  • 2013-05-03
  • 1970-01-01
  • 1970-01-01
  • 2011-10-17
  • 2014-11-01
  • 2016-08-23
  • 2011-11-22
  • 2011-01-09
相关资源
最近更新 更多