2012-06-25 14 views
5

używam SoftGem za VirtualStringTree w Delphi 7.Jak wyświetlić linie siatki wirtualnego drzewa widoku dla węzłów, które jeszcze nie istnieją?

Czy istnieje sposób, aby umożliwić pełne linie siatki (podobnie jak w TListView)? Mogę tylko znaleźć toShowHorzGridLines, który pokazuje tylko linie dla bieżących węzłów, a nie cokolwiek w pustym miejscu poniżej i toShowVertGridLines, który pokazuje tylko pionowe linie.

Jak wyświetlić je w pustym miejscu przed dodaniem elementów?

Odpowiedz

5

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:

enter image description here

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:

enter image description here

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.

+2

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

+0

w ogóle nie jest brudny! to naprawdę całkiem miłe! Dziękuję Ci bardzo! –

+2

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