Nie sądzę, że istnieje prosty sposób implementacji tej metody bez zmiany metody PaintTree
, ponieważ żadne ze zdarzeń węzła nie może zostać uruchomione, ponieważ węzły, których linie powinny być rysowane, po prostu jeszcze nie istnieją.
Oto brudna droga jak dodatkowo narysować linie poziome na podstawie najniższego widocznego węzła. W rzeczywistości to rysuje linie z odległości wartości DefaultNodeHeight
w obszarze wypełnionym przez pomarańczowy kolor w tym zrzucie:
Oto kod:
type
TVirtualStringTree = class(VirtualTrees.TVirtualStringTree)
public
procedure PaintTree(TargetCanvas: TCanvas; Window: TRect; Target: TPoint;
PaintOptions: TVTInternalPaintOptions; PixelFormat: TPixelFormat = pfDevice); override;
end;
implementation
{ TVirtualStringTree }
procedure TVirtualStringTree.PaintTree(TargetCanvas: TCanvas; Window: TRect;
Target: TPoint; PaintOptions: TVTInternalPaintOptions;
PixelFormat: TPixelFormat);
var
I: Integer;
EmptyRect: TRect;
PaintInfo: TVTPaintInfo;
begin
inherited;
if (poGridLines in PaintOptions) and (toShowHorzGridLines in TreeOptions.PaintOptions) and
(GetLastVisible <> nil) then
begin
EmptyRect := GetDisplayRect(GetLastVisible,
Header.Columns[Header.Columns.GetLastVisibleColumn].Index, False);
EmptyRect := Rect(ClientRect.Left, EmptyRect.Bottom + DefaultNodeHeight,
EmptyRect.Right, ClientRect.Bottom);
ZeroMemory(@PaintInfo, SizeOf(PaintInfo));
PaintInfo.Canvas := TargetCanvas;
for I := 0 to ((EmptyRect.Bottom - EmptyRect.Top) div DefaultNodeHeight) do
begin
PaintInfo.Canvas.Font.Color := Colors.GridLineColor;
DrawDottedHLine(PaintInfo, EmptyRect.Left, EmptyRect.Right,
EmptyRect.Top + (I * DefaultNodeHeight));
end;
end;
end;
A oto wynik ze stałym i zmienną wysokość węzła:
Glitch (linie przesunięte z lewej strony) widoczne na powyższym zrzucie to tylko konsekwencja renderowania przerywaną linią. Jeśli ustawisz właściwość LineStyle
w widoku drzewa wirtualnego na lsSolid
, zobaczysz poprawny wynik.
Teraz patrząc na wynik, prostokąt jest przesunięty. Naprawię to później (muszę już iść). Ale wciąż jest to dość brudne rozwiązanie. – TLama
w ogóle nie jest brudny! to naprawdę całkiem miłe! Dziękuję Ci bardzo! –
Uff, pozycje linii były poprawne. Było to spowodowane renderowaniem przerywanym linii. Jednak był błąd. Aby określić prawą granicę linii, użyłem kolumny z indeksem 'Header.Columns.Count - 1' co było nie tak. Jeśli masz np. 2 kolumny i przeniósł drugą do pierwszej pozycji, a indeks, którego powinienem użyć (indeks najbardziej prawej kolumny) wynosił 0, a nie 1 (czym był "Header.Columns.Count - 1"). Teraz używam dla 'GetLastVisibleColumn', co powinno być właściwe. – TLama