2013-03-25 44 views
2

我在TlistView組件中使用OnDrawItem事件來使用自定義顏色繪製內容,但是當滾動列表視圖時會出現一些工件。使用OnDrawItem事件時TListview繪製不正確

enter image description here

這是使用的代碼。

procedure TForm35.FormCreate(Sender: TObject); 
var 
i, j : integer; 
Item : TListItem; 
s : string; 
begin 
    for i:= 0 to 99 do 
    begin 
    Item:=ListView1.Items.Add; 
    for j:= 0 to ListView1.Columns.Count-1 do 
    begin 
     s:= Format('Row %d Column %d',[i+1, j+1]); 
     if j=0 then 
     Item.Caption :=s 
     else 
     Item.SubItems.Add(s); 
    end; 
    end; 
end; 

procedure TForm35.ListView1DrawItem(Sender: TCustomListView; Item: TListItem; 
    Rect: TRect; State: TOwnerDrawState); 
var 
    x, y, i: integer; 
begin 
    if odSelected in State then 
    begin 
    TListView(Sender).Canvas.Brush.Color := clYellow; 
    TListView(Sender).Canvas.Font.Color := clBlack; 
    end 
    else 
    begin 
    TListView(Sender).Canvas.Brush.Color := clLtGray; 
    TListView(Sender).Canvas.Font.Color := clGreen; 
    end; 

    TListView(Sender).Canvas.FillRect(Rect); 
    x := 5; 
    y := (Rect.Bottom - Rect.Top - TListView(Sender).Canvas.TextHeight('Hg')) div 2 + Rect.Top; 
    TListView(Sender).Canvas.TextOut(x, y, Item.Caption); 
    for i := 0 to Item.SubItems.Count - 1 do 
    begin 
    inc(x, TListView(Sender).Columns[i].Width); 
    TListView(Sender).Canvas.TextOut(x, y, Item.SubItems[i]); 
    end; 
end; 

我在Delphi 2007和XE3中測試了這段代碼,但是我得到了相同的結果。我可以如何防止這個問題?

+9

'X:= 5;'是錯誤的。使用'x:= Rect.Left'。 – Abelisto 2013-03-25 03:58:33

+0

@Abelisto,你應該根據你的評論張貼答案!我會爲它投票... – TLama 2013-03-26 01:37:01

回答

5

好的。更改X := 5X := Rect.Left;

而另一種解決方案(可能更準確):

uses 
    Graphics; 

//... Form or something else declarations ... 

implementation 

procedure TForm35.ListView1DrawItem(Sender: TCustomListView; Item: TListItem; Rect: TRect; State: TOwnerDrawState); 
var 
    s: string; 
    ts: TTextStyle; // Text style (used for drawing) 
begin 
    // inherited; 
    // Clear target rectangle 
    // Set Canvas'es Font, Pen, Brush according for Item state 
    // Get into s variable text value of the Cell. 
    ts.Alignment := taLeftJustify; // Horz left alignment 
    ts.Layout := tlCenter;   // Vert center alignment 
    ts.EndEllipsis := True;  // End ellipsis (...) If line of text is too long too fit between left and right boundaries 
    // Other fields see in the Graphics.TTextStyle = packed record 
    ListView1.Canvas.TextRect(
     Rect, 
     Rect.Left, // Not sure, but there are a small chance of this values equal to zero instead of Rect... 
     Rect.Top, 
     s, 
     ts) 
end; 

end. 

此外,要防止一些輕拂......

... 
var 
    b: TBitmap; 
begin 
    b := TBitmap.Create; 
    try 
     b.Widht := Rect.Right - Rect.Left; 
     b.Height := Rect.Bottom - Rect.Top; 
     //... 
     // Draw content on the b.Canvas 
     //... 
     ListView.Canvas.Draw(Rect.Left, Rect.Top, b); 
    finally 
     b.Free; 
    end; 
end; 
+1

+1。非常好的接收! – 2013-03-26 02:26:18