您忘记为不同状态绘制项目。您需要确定该项目当前处于什么状态并根据该状态绘制它。
您可以通过这种方式获得图片上的内容。但是,如果您启用了多选并选择了多个项目,这看起来不太好:
procedure TForm1.ListBox1DrawItem(Control: TWinControl; Index: Integer;
Rect: TRect; State: TOwnerDrawState);
var
Offset: Integer;
begin
with (Control as TListBox) do
begin
Canvas.Font.Color := Font.Color;
if (odSelected in State) then
begin
Canvas.Pen.Color := $00FF9932;
Canvas.Brush.Color := $00FDDDC0;
end
else
begin
Canvas.Pen.Color := Color;
Canvas.Brush.Color := Color;
end;
Canvas.Rectangle(Rect);
Canvas.Brush.Style := bsClear;
Offset := (Rect.Bottom - Rect.Top - Canvas.TextHeight(Items[Index])) div 2;
Canvas.TextOut(Rect.Left + Offset + 2, Rect.Top + Offset, Items[Index]);
end;
end;
结果ItemHeight
设置为 16:

奖金 - 连续选择:
这是一个实现连续选择的棘手解决方案。原理是像以前一样绘制项目,然后根据上一个项目和下一个项目的选择状态,用一种颜色的线覆盖项目的边框顶部和底部线。除此之外,还必须在当前项目之外渲染,因为项目选择不会自然地调用要重新绘制的相邻项目。因此,水平线画在当前项目边界上方一个像素和一个像素下方(这些线的颜色也取决于相对选择状态)。
这里比较奇怪的是使用 item 对象来存储每个 item 的选中状态。我这样做是因为在使用拖放项目选择时,该Selected
属性在您释放鼠标按钮之前不会返回真实状态。幸运的是,OnDrawItem
事件当然会以真实状态触发,因此作为一种解决方法,我使用了从OnDrawItem
事件中存储这些状态。
重要的:
请注意,我正在使用项目对象来存储实际的选择状态,所以要小心,当您将项目对象用于其他用途时,请将此实际状态存储到布尔数组中。
procedure TForm1.ListBox1DrawItem(Control: TWinControl; Index: Integer;
Rect: TRect; State: TOwnerDrawState);
const
SelBackColor = $00FDDDC0;
SelBorderColor = $00FF9932;
var
Offset: Integer;
ItemSelected: Boolean;
begin
with (Control as TListBox) do
begin
Items.Objects[Index] := TObject((odSelected in State));
if (odSelected in State) then
begin
Canvas.Pen.Color := SelBorderColor;
Canvas.Brush.Color := SelBackColor;
Canvas.Rectangle(Rect);
end
else
begin
Canvas.Pen.Color := Color;
Canvas.Brush.Color := Color;
Canvas.Rectangle(Rect);
end;
if MultiSelect then
begin
if (Index > 0) then
begin
ItemSelected := Boolean(ListBox1.Items.Objects[Index - 1]);
if ItemSelected then
begin
if (odSelected in State) then
begin
Canvas.Pen.Color := SelBackColor;
Canvas.MoveTo(Rect.Left + 1, Rect.Top);
Canvas.LineTo(Rect.Right - 1, Rect.Top);
end
else
Canvas.Pen.Color := SelBorderColor;
end
else
Canvas.Pen.Color := Color;
Canvas.MoveTo(Rect.Left + 1, Rect.Top - 1);
Canvas.LineTo(Rect.Right - 1, Rect.Top - 1);
end;
if (Index < Items.Count - 1) then
begin
ItemSelected := Boolean(ListBox1.Items.Objects[Index + 1]);
if ItemSelected then
begin
if (odSelected in State) then
begin
Canvas.Pen.Color := SelBackColor;
Canvas.MoveTo(Rect.Left + 1, Rect.Bottom - 1);
Canvas.LineTo(Rect.Right - 1, Rect.Bottom - 1);
end
else
Canvas.Pen.Color := SelBorderColor;
end
else
Canvas.Pen.Color := Color;
Canvas.MoveTo(Rect.Left + 1, Rect.Bottom);
Canvas.LineTo(Rect.Right - 1, Rect.Bottom);
end;
end;
Offset := (Rect.Bottom - Rect.Top - Canvas.TextHeight(Items[Index])) div 2;
Canvas.Brush.Style := bsClear;
Canvas.Font.Color := Font.Color;
Canvas.TextOut(Rect.Left + Offset + 2, Rect.Top + Offset, Items[Index]);
end;
end;
结果:
