Delphi:在ListViewDrawItem上绘制选择和鼠标悬停效果

时间:2011-07-07 22:04:36

标签: delphi listview drawing hover selection

我有一个代码来自:Delphi: Canvas.FillRect in List View来绘制行(我使用OwnerDraw)。

因此我需要绘制选择和鼠标悬停效果。并绘制正常的列调整大小效果......

我有一个代码可以上下移动项目:

procedure TForm1.ListViewDragDrop(Sender, Source: TObject; X,
  Y: Integer);
var
  DragItem, DropItem, CurrentItem, NextItem: TListItem;
begin
  if Sender = Source then
    with TListView(Sender) do
    begin
      DropItem    := GetItemAt(X, Y);
      CurrentItem := Selected;
      while CurrentItem <> nil do
      begin
        NextItem := GetNextItem(CurrentItem, SdAll, [IsSelected]);
        if DropItem = nil then DragItem := Items.Add
        else
          DragItem := Items.Insert(DropItem.Index);
        DragItem.Assign(CurrentItem);
        CurrentItem.Free;
        CurrentItem := NextItem;
      end;
    end;
end;

procedure TForm1.ListViewDragOver(Sender, Source: TObject; X, Y: Integer;
  State: TDragState; var Accept: Boolean);
begin
Accept := Sender = Update_ListBox;
end;

如何在ListViewDrawItem +列调整大小效果上绘制选择和鼠标悬停效果?

感谢!!!

1 个答案:

答案 0 :(得分:2)

如果要绘制选择并以其他方式响应控件的当前状态,则需要为此目的编写其他代码,因为我们是所有者绘制控件。这意味着我们对Windows说,“嘿,不要在客户区绘制任何东西,我会这样做”。因此,Windows不会绘制任何内容,甚至不会选择,焦点矩形和鼠标悬停效果。

幸运的是,手动实现此行为相当容易。实际上,在OnCustomDraw事件处理程序中,您将获得一个State参数,您可以阅读该参数。这是一个集合,一些可能的元素包括odSelectedodHotLightodFocused

根据我们之前的代码,只添加几行新内容,我们到达

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 := clWhite;
      Sender.Canvas.Brush.Color := clGreen;
  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;
  if odSelected in State then                                                    // NEW!
  begin                                                                          // NEW!
    Sender.Canvas.Font.Color := clWhite;                                         // NEW!
    Sender.Canvas.Brush.Color := clNavy;                                         // NEW!
  end;                                                                           // NEW!
  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;
  if odFocused in State then                                                     // NEW!
    DrawFocusRect(Sender.Canvas.Handle, Rect);                                   // NEW!
end;

Screenshot http://privat.rejbrand.se/TListViewCustomDrawIconSelState.png

请注意,“马”行已被选中且具有键盘焦点。