在TListView中居中子项目图像

问题描述 投票:2回答:1

是否有可能在subitem中修复TListView图像的绘制,以便它们不会在左侧切断,如图所示? enter image description here

delphi tlistview subitem
1个回答
3
投票

好吧,Pieter van Wyk,我做了一个很小的例子,你可以如何拥有你的TListView组件,以便将图像置于子项目中。

答案已被重写。为了减少答案的大小,我删除了未使用和错误的部分。以前的版本可以在问题编辑的历史中找到。

下图表示新代码的工作。 一个橙色行是选定的行。 enter image description here 所选行上的图像周围有白色。这不是一个错误 - 它是一个带有这种填充的源图像。

有一些代码允许在图片上做同样的事情:

procedure TForm1.ListView1DrawItem(Sender: TCustomListView; Item: TListItem; Rect: TRect;
  State: TOwnerDrawState);
var
  Bmp: TBitmap;
  Image: TBitmap;
  R: TRect;
  CenterH: Integer;
  CenterV: Integer;
  ImageIndex: Integer;
  ItemWidth: Integer;
  i: Integer;
begin
  // Set initial legth of point at the end of which image will be drawn.  
  // Column 0 is a "fixed" column
  ItemWidth := Sender.Column[0].Width;
  R := Rect;

  Bmp := TBitmap.Create;
  try
    Image := TBitmap.Create;
    try
      Bmp.SetSize(R.Width, R.Height);

      // Make fill for item
      if Item.Selected then
        Bmp.Canvas.Brush.Color := clWebOrange
      else
        Bmp.Canvas.Brush.Color := clMoneyGreen;
      Bmp.Canvas.FillRect(Bmp.Canvas.ClipRect);

      // Output image associated with 'fixed' column
      TListView(Sender).SmallImages.GetBitmap(Item.ImageIndex, Image);
      CenterH := (Sender.Column[0].Width - Image.Width) div 2;
      CenterV := (R.Height - Image.Height) div 2;
      Bmp.Canvas.Draw(CenterH, CenterV, Image);

      // Output text
      Bmp.Canvas.TextOut(CenterH + Image.Width + 6, 6, Item.Caption);

      // Draw sub-items
      for i:=0 to Item.SubItems.Count - 1 do
        begin
          // Obtain index of image
          ImageIndex := Item.SubItemImages[i];

          // Get associated image
          TListView(Sender).SmallImages.GetBitmap(ImageIndex, Image);

          // Center image
          CenterH := (Sender.Column[i+1].Width - Image.Width) div 2;
          CenterV := (R.Height - Image.Height) div 2;

          // Output image
          Bmp.Canvas.Draw(ItemWidth + CenterH, CenterV, Image);

          // Increase point where image started to be drawn
          Inc(ItemWidth, Sender.Column[i+1].Width);
        end;

      // Draw ready item's image onto sender's canvas
      Sender.Canvas.Draw(R.Left, R.Top, Bmp);
    finally
      Image.Free;
    end;
  finally
    Bmp.Free;
  end;
end;

要应用此代码,您必须激活OwnerDraw属性。

看到这导致TListView.OwnerDraw Propertydocs.embarcadero。我还想从上面的链接中显示引用:

将OwnerDraw设置为true以允许列表视图接收OnDrawItem事件而不是列表项的默认呈现。

附: 在调整了列的大小之后,可能会有一些graphical artifacts - 只是尝试以隐藏(最小可能的列大小)的方式调整列的大小并显示图像(任何大小的列将超过相关图像的大小),你会看到什么我的意思是。

P.S.S. 绘制我作为家庭作业留给你的子项目的文本;)

最新问题
© www.soinside.com 2019 - 2024. All rights reserved.