Delphi: Canvas.FillRect в представлении списка
При изменении текста подэлемента представления списка мне нужно почистить и заполнить целый ряд:
procedure TForm1.ListViewDrawItem(Sender: TCustomListView;
Item: TListItem; Rect: TRect; State: TOwnerDrawState);
begin
if Item.SubItems[2]='Done'
then
begin
Sender.Canvas.Font.Color := clBlack;
Sender.Canvas.Brush.Color := clGreen;
Sender.Canvas.Brush.Style := bsSolid;
Sender.Canvas.FillRect(Rect);
end;
end;
Но отправитель. Канва.FillRect (Rect) заполнит только Rect подэлемента. Как заполнить целый ряд?
Вопрос задается на основе Delphi: как рисовать маленькие иконки в List View на CustomDrawItem
Спасибо!
1 ответ
Во-первых, если у вас есть три столбца, они Caption
, SubItems[0]
, а также SubItems[1]
, Помните? Здесь нет SubItems[2]
!
Во всяком случае, это очень легко. Вам нужна только очень и очень маленькая модификация старого кода.
procedure TForm1.ListView1DrawItem(Sender: TCustomListView; Item: TListItem;
Rect: TRect; State: TOwnerDrawState);
var
i: Integer;
x1, x2: integer;
r: TRect;
S: string;
const
DT_ALIGN: array[TAlignment] of integer = (DT_LEFT, DT_RIGHT, DT_CENTER);
begin
if SameText(Item.SubItems[1], 'done') then
begin
Sender.Canvas.Font.Color := clBlack;
Sender.Canvas.Brush.Color := clLime;
end
else
if Odd(Item.Index) then
begin
Sender.Canvas.Font.Color := clBlack;
Sender.Canvas.Brush.Color := $F6F6F6;
end
else
begin
Sender.Canvas.Font.Color := clBlack;
Sender.Canvas.Brush.Color := clWhite;
end;
Sender.Canvas.Brush.Style := bsSolid;
Sender.Canvas.FillRect(Rect);
x1 := 0;
x2 := 0;
r := Rect;
Sender.Canvas.Brush.Style := bsClear;
Sender.Canvas.Draw(3, r.Top + (r.Bottom - r.Top - bm.Height) div 2, bm);
for i := 0 to ListView1.Columns.Count - 1 do
begin
inc(x2, ListView1.Columns[i].Width);
r.Left := x1;
r.Right := x2;
if i = 0 then
begin
S := Item.Caption;
r.Left := bm.Width + 6;
end
else
S := Item.SubItems[i - 1];
DrawText(Sender.Canvas.Handle,
S,
length(S),
r,
DT_SINGLELINE or DT_ALIGN[ListView1.Columns[i].Alignment] or
DT_VCENTER or DT_END_ELLIPSIS);
x1 := x2;
end;
end;
http://privat.rejbrand.se/TListViewCustomDrawIconSel.png
Обратите особое внимание на то, что я использую clLime
вместо clGreen
, так как clBlack
текст на clGreen
фон выглядит ужасно! Вы могли бы рассмотреть clWhite
текст на clGreen
фон, хотя:
http://privat.rejbrand.se/TListViewCustomDrawIconSel2.png
Обновление в ответ на комментарии:
Чтобы изменить третий столбец представления списка, это не просто
procedure TForm1.FormClick(Sender: TObject);
begin
ListView1.Items[3].SubItems[1] := 'Done';
end;
Действительно, Windows не знает, что данные одного столбца влияют на внешний вид всей строки! Самое простое исправление - сказать Windows перекрасить весь элемент управления, когда вы изменили значение Лучше: просто скажите Windows перерисовать текущую строку:
procedure TForm1.FormClick(Sender: TObject);
begin
ListView1.Items[3].SubItems[1] := 'Done';
ListView1.Items[3].Update;
end;