![]() |
TVirtualStringTree AutoFitColumns erste Spalte wird nicht angepasst
Hallo,
ich arbeite schon lange mit der Komponente TVirtualStringTree aber das Verhalten habe ich bisher noch nicht erlebt. Aber was passiert, ich versuche mit 'AutoFitColumns' die Spalten an den Inhalt bzw. die Überschrift anzupassen aber in einer Situation wird partout die erste Spalte ignoriert und erst die darauf folgenden Spalten korrekt angepasst. Wie sonst auch führe ich nach dem Ändern eines Eintrags folgenden Befehl aus um alle Spalten anzupassen, aber die erste Spalte bleibt unverändert und wird nicht vergrößert.
Delphi-Quellcode:
Das kuriose ist das es beim ersten befüllen der Komponente klappt nur nicht wenn ich Einträge ändern will. Ich hoffe jemand von euch hat einen Tipp. Leider kann ich nicht ohne das halbe Projekt online zu stellen euch mehr Quellcode zeigen.
vstTable.Header.AutoFitColumns(False, smaUseColumnOption, 0, vstTable.Header.Columns.Count-1);
|
AW: TVirtualStringTree AutoFitColumns erste Spalte wird nicht angepasst
Hallo Tux,
ich nutze die Funktion zwar nicht da ich immer selbst die Breite der Columns angebe, habe aber im SourceCode gesehen, dass vor dem Ausführen des Sizing das Event
Delphi-Quellcode:
ausgelöst wird (wenn denn ein EventHandler existiert).
OnBeforeAutoFitColumns
Hier gibt es einen Parameter
Delphi-Quellcode:
. Setzt du diesen an irgendeiner Stelle auf einen anderen Wert oder nutzt du das Event überhaupt?
var SmartAutoFitType: TSmartAutoFitType
Wenn nicht, dann steht (wie du es beim Aufruf auch übergibst) die Option auf
Delphi-Quellcode:
.
smaUseColumnOption
Und das ist der Knackpunkt. Hast du auch bei deiner ersten Column die Option in den ColumnOptions eingeschaltet? |
AW: TVirtualStringTree AutoFitColumns erste Spalte wird nicht angepasst
Zitat:
Delphi-Quellcode:
verwende ich nicht in dem Projekt, das komische ist es das ja eigentlich alles funktioniert und richtig ist nur beim Ändern eines Eintrags will er einfach nicht die erste Spalte anpassen. Füge ich einen weiteren Eintrag hinzu, wird die Spalte korrekt angepasst.
OnBeforeAutoFitColumns
Delphi-Quellcode:
Jetzt passiert folgendes, Spalte 2 hat die korrekte und angepasste Breite und Spalte 1 bleibt unverändert und somit zu klein. Dazu kommt noch das erst wenn ich auf eine andere Zeile wechsle werden in der 1. Spalte die drei Punkte gezeichnet.
var
Node: PVirtualNode; Data: PDataset; begin Node := vstTable.FocusedNode; if Assigned(Node) then begin Data := vstTable.GetNodeData(Node); if Assigned(Data) then begin Data.Name := edtName.Text; //1. Spalte, hier wird eine längere Bezeichnung eingegeben Data.Type := edtType.Text; //2. Spalte, hier wird ebenfalls etwas längeres Eingetragen end; end; //Spalten anpassen... vstTable.Header.AutoFitColumns(False, smaUseColumnOption, 0, vstTable.Header.Columns.Count-1); |
AW: TVirtualStringTree AutoFitColumns erste Spalte wird nicht angepasst
Zitat:
Delphi-Quellcode:
Diese muss jedoch nicht immer zwingend mit dem ColumnIndex übereinstimmen. Vielleicht liegt es ja daran.
AutoFitColumns(True, smaUseColumnOption, FColumns[FColumns.FTrackIndex].FPosition, FColumns[FColumns.FTrackIndex].FPosition)
Ansonsten kann es fast nur noch an den Optionen für die Spalte bzw. den Tree liegen madas |
AW: TVirtualStringTree AutoFitColumns erste Spalte wird nicht angepasst
Hast du dir denn auch die ColumnOptions der ersten Column angeschaut? Ist dort die entsprechende Option aktiviert?
|
AW: TVirtualStringTree AutoFitColumns erste Spalte wird nicht angepasst
Zitat:
|
AW: TVirtualStringTree AutoFitColumns erste Spalte wird nicht angepasst
Zitat:
Delphi-Quellcode:
nix
DefaultColumnOptions = [coAllowClick, coDraggable, coEnabled, coParentColor, coParentBidiMode, coResizable, coShowDropmark, coVisible, coAllowFocus, coEditable];
Delphi-Quellcode:
zu sehen.
coSmartResize
|
AW: TVirtualStringTree AutoFitColumns erste Spalte wird nicht angepasst
Zitat:
Delphi-Quellcode:
Ändere ich den Inhalt z.B. in Spalte 2 wird die Spalte sofort angepasst, neu gezeichnet und alles ist wunderbar.
vstTable.invalidate
|
AW: TVirtualStringTree AutoFitColumns erste Spalte wird nicht angepasst
Zitat:
Delphi-Quellcode:
not TreeView.OperationCanceled
procedure DoAutoFitColumn(Column: TColumnIndex);
begin with FColumns do if ([coResizable, coVisible] * Items[FPositionToIndex[Column]].FOptions = [coResizable, coVisible]) and DoBeforeAutoFitColumn(FPositionToIndex[Column], SmartAutoFitType) and not TreeView.OperationCanceled then begin if Animated then AnimatedResize(FPositionToIndex[Column], Treeview.GetMaxColumnWidth(FPositionToIndex[Column], GetUseSmartColumnWidth(FPositionToIndex[Column]))) else FColumns[FPositionToIndex[Column]].Width := Treeview.GetMaxColumnWidth(FPositionToIndex[Column], GetUseSmartColumnWidth(FPositionToIndex[Column])); DoAfterAutoFitColumn(FPositionToIndex[Column]); end; end; Binde doch die Unit einfach mal in Dein Projekt ein und debugge das Ganze. Viel Erfolg. madas |
AW: TVirtualStringTree AutoFitColumns erste Spalte wird nicht angepasst
Es wird immer lustiger, ich gucke gerade was den
Delphi-Quellcode:
so tatsächlich macht.
AutoFitColumns
Delphi-Quellcode:
Irgendwie scheint
ShowMessage(vstTable.GetMaxColumnWidth(0, True).ToString); //Hier ist die Spalte 69px breit
ShowMessage(vstTable.GetMaxColumnWidth(1, True).ToString); //Hier ist die Spalte 49px breit Node := vstTable.FocusedNode; if Assigned(Node) then begin Data := vstTable.GetNodeData(Node); if Assigned(Data) then begin Data.Name := 'skljglsjfgskjfsldjfksjlfkjsd'; //neuer Text ist länger als alle anderen Data.Type := 'dfkgjdkjgfklgjdkjgkljgkdjkkgdljgkdjgdgfdgld'; //neuer Text ist länger als alle anderen end; end; ShowMessage(vstTable.GetMaxColumnWidth(0, True).ToString); //Hier ist die Spalte 69px breit -> FALSCH ShowMessage(vstTable.GetMaxColumnWidth(1, True).ToString); //Hier ist die Spalte 129px breit -> RICHTIG
Delphi-Quellcode:
beim Ändern des Inhaltes von Spalte 1 zu versagen ..
GetMaxColumnWidth
|
AW: TVirtualStringTree AutoFitColumns erste Spalte wird nicht angepasst
Dann mache die Berechnung doch selber. :)
Wir machen das bei uns so (ist ein Frame mit einem VST drauf, der Tree als Name hat):
Delphi-Quellcode:
function TFrameVST.GetMaxHeaderWidth(const Column: TColumnIndex): Integer;
var col: TVirtualTreeColumn; Size: TSize; begin col := Tree.Header.Columns[Column]; Result := 2 * col.Margin; if (Length(col.Text) > 0) then begin Tree.Canvas.Font := Tree.Header.Font; GetTextExtentPoint32W(Tree.Canvas.Handle, PWideChar(col.Text), Length(col.Text), Size); Inc(Result, Size.cx + 4); end; if (hoShowImages in Tree.Header.Options)and(Assigned(Tree.Header.Images)) then Inc(Result,(Tree.Header.Images.Width + col.Spacing)); if (hoShowSortGlyphs in Tree.Header.Options)and(Tree.Header.SortColumn = Column) then begin Inc(Result, 20); // Platz für Sortimage if (col.CaptionAlignment = taCenter) then Inc(Result, 14); // mehr Platz für Sortimage berücksichtigen end; if Result < col.MinWidth then Result := col.MinWidth; if Result > col.MaxWidth then Result := col.MaxWidth; end; procedure TFrameVST.AutoFitColumn(Column: TColumnIndex); var cWidth, hWidth: Integer; begin if [coResizable, coVisible] * Tree.Header.Columns[Column].Options = [coResizable, coVisible] then begin if (hoVisible in Tree.Header.Options) then begin hWidth := GetMaxHeaderWidth(Column); cWidth := Tree.GetMaxColumnWidth(Column); if cWidth < hWidth then cWidth := hWidth; if cWidth > Tree.Header.Columns[Column].MaxWidth then cWidth := Tree.Header.Columns[Column].MaxWidth; Tree.Header.Columns[Column].Width := cWidth; end; end; end; procedure TFrameVST.AutoFitColumns; var Column: TColumnIndex; merkCursor: TCursor; begin merkCursor := Screen.Cursor; Tree.BeginUpdate; try Screen.Cursor := crHourGlass; for Column := 0 to Tree.Header.Columns.Count-1 do AutoFitColumn(Column); finally Screen.Cursor := merkCursor; Tree.EndUpdate; end; end; FmerkOnBeforeCellPaint: TVTBeforeCellPaintEvent; procedure TFrameVST.TreeBeforeGetMaxColumnWidth(Sender: TVTHeader; Column: TColumnIndex; var UseSmartColumnWidth: Boolean); begin if Assigned(Tree.OnBeforeCellPaint) then begin FmerkOnBeforeCellPaint := Tree.OnBeforeCellPaint; Tree.OnBeforeCellPaint := nil; end; end; procedure TFrameVST.TreeAfterGetMaxColumnWidth(Sender: TVTHeader; Column: TColumnIndex; var MaxWidth: Integer); begin if Assigned(FmerkOnBeforeCellPaint) then begin Tree.OnBeforeCellPaint := FmerkOnBeforeCellPaint; FmerkOnBeforeCellPaint := nil; end; end; |
AW: TVirtualStringTree AutoFitColumns erste Spalte wird nicht angepasst
Am Rande bemerkt: Du könntest das auch ein bisschen abkürzen, weil GetNodeData Failsafe ist:
Delphi-Quellcode:
Davon abgesehen, du hast nicht zufällig Header.AutoSizeIndex auf 0 stehen?
Node := vstTable.FocusedNode;
Data := vstTable.GetNodeData(Node); if Assigned(Data) then begin Data.Name := 'skljglsjfgskjfsldjfksjlfkjsd'; //neuer Text ist länger als alle anderen Data.Type := 'dfkgjdkjgfklgjdkjgkljgkdjkkgdljgkdjgdgfdgld'; //neuer Text ist länger als alle anderen end; |
AW: TVirtualStringTree AutoFitColumns erste Spalte wird nicht angepasst
Zitat:
Delphi-Quellcode:
, und das führt bei mir ja zu einem Falschen Ergebnis.
GetMaxColumnWidth
Wäre es möglich mir die Optionen und Eigenschaften der Komponente zu zeigen, also das was in der *.dfm Datei steht? Damit ich das mit meinen Eigenschaften vergleichen kann. |
AW: TVirtualStringTree AutoFitColumns erste Spalte wird nicht angepasst
Nochwas: müssten das nicht dereferenzierte Pointer sein?
Delphi-Quellcode:
Node := vstTable.FocusedNode;
Data := vstTable.GetNodeData(Node); if Assigned(Data) then begin Data^.Name := 'skljglsjfgskjfsldjfksjlfkjsd'; //neuer Text ist länger als alle anderen Data^.Type := 'dfkgjdkjgfklgjdkjgkljgkdjkkgdljgkdjgdgfdgld'; //neuer Text ist länger als alle anderen end; |
AW: TVirtualStringTree AutoFitColumns erste Spalte wird nicht angepasst
Zitat:
Zitat:
Delphi-Quellcode:
ändert sich nichts.
Data^.Name :=
|
AW: TVirtualStringTree AutoFitColumns erste Spalte wird nicht angepasst
Zeig mal bitte die Deklaration von PDataSet. Mein Verdacht ist, weil ich das beim VST schon mehrfach hatte: Speichersalat wegen wildem Pointergeschubse.
EDIT: Den Kommentar in der Implementierung von GetMaxColumnWidth hast du gesehen?
Delphi-Quellcode:
So wie du das machst bezieht sich die Kalkulation nur auf die im Viewport sichtbaren Nodes. Falls der betreffende Node aber gerade out-of-Scroll ist oder Collapsed, dann wird der nicht einbezogen.
// This method determines the width of the largest node in the given column.
// If UseSmartColumnWidth is True then only the visible nodes which are in view will be considered // Note: If UseSmartColumnWidth is False then every visible node in the tree will be initialized contradicting so // the virtual paradigm. |
AW: TVirtualStringTree AutoFitColumns erste Spalte wird nicht angepasst
Bei PDataset handelt es sich um einen Zeiger auf eine Klasse.
Delphi-Quellcode:
Beim befüllen bzw. hinzufügen von Einträgen wird entsprechend das Objekt erstellt
TDataset = class(TObject)
private FName: String; FType: String; public constructor Create; destructor Destroy; override; property Name: String read FName write FName; property Type: String read FType write FType; end; PDataset = ^TDataset;
Delphi-Quellcode:
Die Zelle die ich versuche zu ändern ist nicht nur sichtbar sondern hat auch noch den Focus.
Node := vstTable.AddChild(nil);
if Assigned(Node) then begin Data := vstTable.GetNodeData(Node); if Assigned(Data) then begin //init Data^ := TDataset.Create; Data.Name := 'bla bla'; Data.Type := 'bla bla'; end; end; |
AW: TVirtualStringTree AutoFitColumns erste Spalte wird nicht angepasst
Oh je....
Ich ahnte es. Speichersalat. Ich habe zumindest noch nie gesehen, dass man den VST mit Klasseninstanzen statt Records verwendet. Habe es auch noch nie probiert, weil alle Beispiele und Tutorials die ich so kenne alle auf Records basieren. Ändere die Deklaration von TDataSet doch bitte mal testweise so um:
Delphi-Quellcode:
TDataset = record
Name: String; Type: String; end; |
AW: TVirtualStringTree AutoFitColumns erste Spalte wird nicht angepasst
Zitat:
Also daran ist nichts falsch und es ist auch definitiv nicht die Ursache warum das AutoSizing nicht funktioniert. |
AW: TVirtualStringTree AutoFitColumns erste Spalte wird nicht angepasst
Zitat:
Delphi-Quellcode:
Und dann da die Klasseninstanzen angehangen.
type
TNodeData = record ObjRef: Pointer; end; Aber so wie hier gemacht, stelle ich mir das seltsam vor. GetNodeData erzeugt erst eine neue Variableninstanz vom Typ Pointer mit der Größe von [was eigentlich? -> OnGetNodeDataSize], dann lässt man den Speichermanager durch TDataSet.Create eine neue Klasseninstanz auf der selben Adresse erzeugen und dann überlässt man das der internen Speicherverwaltung vom VST? Hmm, ok, ich arbeite immer noch mit der letzten Lischke-Version vom VST. Vielleicht sind neuere dahingehend flexibler. Wie gesagt, ich habe das nie so gemacht. NACHTRAG: Um wieder auf das eigentliche Problem zurück zu kommen: GetMaxColumnWidth arbeitet ja intern mit Canvas.TextWidth. Wenn man da jetzt dummerweise nicht den String sondern eine getypcastete Referenz auf den String rein wirft, erhält man recht gern den Effekt, dass TextWidth immer identische Werte ausspuckt. Würde also theoretisch das Problem erklären. |
AW: TVirtualStringTree AutoFitColumns erste Spalte wird nicht angepasst
Zitat:
Jetzt habe mich mal für Spaß die Option
Delphi-Quellcode:
auf 1 gesetzt und siehe da es funktioniert, die erste und auch die zweite Spalte werden angepasst. So bald aber MainColumn wieder auf 0 oder -1 steht klappt es nicht.
vstTable.Header.MainColumn
|
AW: TVirtualStringTree AutoFitColumns erste Spalte wird nicht angepasst
Ok, ich verstehe es zwar nicht so ganz aber ich glaube ich habe die Ursache gefunden. Weil die Zeile ja immer noch den Focus hat und ausgewählt ist wird wohl intern der Inhalt für die erste Spalte geändert so das bei der Berechnung der maximalen Breite keine Veränderung erkannt wird. Hebe ich die Auswahl vor dem Ändern auf klappt es und auch die erste Spalte wird korrekt geändert.
Delphi-Quellcode:
procedure TForm2.Button1Click(Sender: TObject);
var Node: PVirtualNode; Data: PMyDataSet; begin ShowMessage(IntToStr(vstTable.GetMaxColumnWidth(0, False))); //62px ShowMessage(IntToStr(vstTable.GetMaxColumnWidth(1, False))); //77px vstTable.BeginUpdate; Node := vstTable.FocusedNode; vstTable.ClearSelection; //Auswahl aufheben if Assigned(Node) then begin Data := vstTable.GetNodeData(Node); if Assigned(Data) then begin Data.Name := Data.Name + 'xyz 12345'; Data.Desc := Data.Desc + 'xyz 12345'; end; end; vstTable.EndUpdate; vstTable.FocusedNode := Node; //Zeile wieder auswählen vstTable.Selected[Node] := True; //und markieren ShowMessage(IntToStr(vstTable.GetMaxColumnWidth(0, False))); //106px ShowMessage(IntToStr(vstTable.GetMaxColumnWidth(1, False))); //127px vstTable.Header.AutoFitColumns(False, smaAllColumns); end; |
AW: TVirtualStringTree AutoFitColumns erste Spalte wird nicht angepasst
Nachtrag:
An Stelle davon die Auswahl aufzuheben und wieder zu setzen kann man auch per
Delphi-Quellcode:
den einzelnen Knoten aktualisieren und dann klappt auch wieder die Berechnung. Trotz alle dem scheint mir das Verhalten etwas merkwürdig zu sein, aber gut mit dieser Lösung kann ich arbeiten.
vstTable.InvalidateNode(Node);
Vielen Dank bei allen Beteiligten, wünsche euch noch einen schönen Tag ;-) |
AW: TVirtualStringTree AutoFitColumns erste Spalte wird nicht angepasst
Hallo TUX,
nachdem du das jetzt so sagst erinnere ich mich an etwas. Ich hatte mir mal die Funktion angeschaut wie der VST denn die Berechnung macht ab wann er den Text abschneiden soll. Und das kann er ja nur dann wissen, wenn er die Font Größe und die Breite des Textes auf dem entsprechenden Canvas kennt. Dein Abwählen der Node hat intern ein Invalidate ausgelöst. Somit ist der Text auf dem Canvas neu gezeichnet worden und die Textbreite kann ermittelt werden. Der Tree weiß ja nicht, wie er auf deine internen Daten zugreifen soll. Das manuelle Invalidate musst du aufrufen, da du, ohne das Wissen des Trees, die internen Daten veränderst. Würdest du das über einen Editor machen, dann wüsste er es und würde automatisch ein Invalidate veranlassen. Also von daher ganz logisch! :thumb: |
AW: TVirtualStringTree AutoFitColumns erste Spalte wird nicht angepasst
Zitat:
|
AW: TVirtualStringTree AutoFitColumns erste Spalte wird nicht angepasst
Die Spalte 0 ist insofern etwas besonderes weil dort der Baum, die Nodebuttons, Treelines usw. gezeichnet werden. Da wird intern beim VST sehr viel anders gemacht als bei anderen Spalten. Weil es nicht immer die Möglichkeit gab, die MainColumn zu verstellen, also in früheren VST-Versionen mal hartcodiert "0" war, möchte ich auch nicht ausschließen dass irgendwo noch so eine "harte Null" überlebt hat.
Zitat:
Gerade weil der VST so ein Featuremonster ist, hat man eben auch 1001 Möglichkeiten, im Zusammenspiel mit der externen Logik Bugs einzubauen. Das Herumraten bringt eigentlich nicht sehr viel, man kann das wahrscheinlich nur am konkreten Code debuggen. EDIT: Zitat:
|
AW: TVirtualStringTree AutoFitColumns erste Spalte wird nicht angepasst
Zitat:
Ich habe inzwischen eine Lösung gefunden wenn ich nach dem Ändern des Inhalt
Delphi-Quellcode:
durchführe funktioniert die Berechnung und Anpassung aller Spalten in der Zeile.
vstTable.InvalidateNode(Node);
|
AW: TVirtualStringTree AutoFitColumns erste Spalte wird nicht angepasst
Zitat:
Der VirtualStringTree liest die Daten nicht selbst aus. Er kennt diese nicht einmal. Er reserviert lediglich den Speicher für dich, den du im OnGetNodeDataSize Event oder per Setzen der Property übergeben hast. Die Texte werden immer per OnGetText Event an den Tree weitergegeben. Du musst dem Tree sagen was er in die einzelnen "Cells" reinschreiben soll. Deshalb ist es auch kein Problem eine Klasse dafür zu verwenden. Das was dann nämlich in NodeData gespeichert wird, ist nur eine Referenz auf die Klasseninstanz. Und die ist (wenn ich mich richtig erinnere) immer 4 Byte (Win32) und 8 Byte (Win64) groß (was nebenbei bemerkt schon der Standardwert der NodeDataSize Property bei Win32 ist). Wenn man dann zu der Klasse noch eine TObjectList mitführt, dann braucht man auch das OnFreeNode Event nicht mehr zu nutzen. Denn die Daten und die Anzahl der Nodes kommen immer aus der TObjectList. Und die Instanzen die darin gespeichert sind, die werden sowieso von dir verwaltet. |
AW: TVirtualStringTree AutoFitColumns erste Spalte wird nicht angepasst
Haste vollkommen recht. Siehe mein Edit oben. Hat sich jetzt zeitlich nur überschnitten.
|
AW: TVirtualStringTree AutoFitColumns erste Spalte wird nicht angepasst
Zitat:
|
AW: TVirtualStringTree AutoFitColumns erste Spalte wird nicht angepasst
Zitat:
Zitat:
Es ist so, dass bei jeder Änderung des Trees, die die Oberfläche betrifft, ein Invalidate des entsprechenden Bereiches ausgelöst wird. Bei ihm wurde das gemacht, weil er die FocusedNode Property gesetzt hat und somit die "Focused Umrandung" (keine Ahnung wie ich das besser beschreiben soll, diese gepunktete Linie die angibt, dass die Node den Focus hat) auf eine andere Node bzw. auf keine Node neu gezeichnet wurde. Hierdurch wurde dann auch gleich wieder das Berechnen der Spaltenbreite ausgelöst. Die vorherige Spaltenbreite bzw. die Breite der einzelnen Inhalte muss der Tree ja auch nicht kennen. Er durchläuft lediglich die Nodes und holt sich per GetText Event den Inhalt. Die Breite dieses Textes wird dann Canvas bezogen errechnet. Der größte Wert wird dann als Spaltenbreite übernommen. Dazu kommt dann noch TextMargins + NodeLevel(Node) * Indent usw. |
AW: TVirtualStringTree AutoFitColumns erste Spalte wird nicht angepasst
Ich denke der gedankliche Fehler hierbei ist, dass der gezeichnete Cell-Content in irgendeiner Weise Auswirkung auf das Ergebnis von GetMaxColumnWidth hätte. Dem ist aber IMHO nicht so. Vielmehr sind gerade solche Dinge wie FocusBorder (das gepunktete Dingens) von ihrem Platzbedarf her von vornherein sozusagen reserviert (teilweise über VST-Properties konfigurierbar). Das einzige wo sich hier die MainColumn von anderen unterscheidet ist der dynamische Teil mit den Indents. Also Node expanded oder nicht, mit Childnodes oder nicht, mit NodeButton oder nicht usw.
Deshalb bin ich auch der Ansicht, dass ein InvalidateNode keine Auswirkungen auf das Ergebnis von GetMaxColumnWidth haben dürfte. Es sei denn, man würde eventgesteuert die externen Daten zwischendurch verändern. Was ja, wie bereits geschrieben, nur anhand des konkreten Projektes nachvollziehbar ist und nicht allein anhand des VST-Codes den wir alle haben. |
AW: TVirtualStringTree AutoFitColumns erste Spalte wird nicht angepasst
Zitat:
Ein InvalidateNode führt nur dazu, dass der gesamte Tree neu und dementsprechend die im Hintergrund geänderten Daten auf dem Tree gezeichnet werden. Ein Aufruf vom eigentlichen AutoFitColumns() würde ja praktisch implizit ein Invalidate aufrufen. |
AW: TVirtualStringTree AutoFitColumns erste Spalte wird nicht angepasst
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:
Delphi-Quellcode:
hat aber eine Auswirkung darauf, zumindest soweit das die Berechnung danach funktioniert. Ich weiß doch auch nicht wieso das so ist.
InvalidateNode()
Damit ihr euch das auch ansehen könnt habe ich eine Mini Anwendung (siehe Anhang) gebaut die das Verhalten wie mein eigentliches Projekt aufweist. |
AW: TVirtualStringTree AutoFitColumns erste Spalte wird nicht angepasst
Tja da hat wohl jemand das "^" beim Zugriff auf Data vergessen.
alt:
Delphi-Quellcode:
so wie es muss:
Node := vstTable.FocusedNode;
if Assigned(Node) then begin Data := vstTable.GetNodeData(Node); if Assigned(Data) then begin Data.Name := Data.Name + 'xyz 12345'; Data.Desc := Data.Desc + 'xyz 12345'; end; end;
Delphi-Quellcode:
Beim OnGetText genau so. Usw.
Node := vstTable.FocusedNode;
if Assigned(Node) then begin Data := vstTable.GetNodeData(Node); if Assigned(Data) then begin Data^.Name := Data^.Name + 'xyz 12345'; Data^.Desc := Data^.Desc + 'xyz 12345'; end; end; |
AW: TVirtualStringTree AutoFitColumns erste Spalte wird nicht angepasst
Zitat:
|
AW: TVirtualStringTree AutoFitColumns erste Spalte wird nicht angepasst
Zitat:
![]() |
AW: TVirtualStringTree AutoFitColumns erste Spalte wird nicht angepasst
Zitat:
|
AW: TVirtualStringTree AutoFitColumns erste Spalte wird nicht angepasst
@TUX_der_Pinguin: Mal dumm gefragt: Verwendest du den VST als Tree oder als Grid? Sprich, brauchst du das ganze Aufklapp-Gedönse überhaupt? Denn wenn nicht, setzt du einfach Header.MainColumn auf 1 und der Fehler ist umgangen.
Jetzt kann ich zumindest das Problem nachvollziehen. Hinzu kommt, die drei "Abkürzungspünktchen" werden auch nicht korrekt angezeigt wenn man die Spalte 0 danach manuell verkleinert. Erst nach einem Invalidate (implizit durch Fokuswechsel) wird der Node richtig initialisiert. Das spräche ja dafür, dass der VST doch irgendwas intern puffert. Sehr seltsam. Besonders deutlich wird das Problem, wenn man TreeOptions.StringOptions.toShowStaticText setzt. Dann überlappen sich in Spalte 0 sogar die Texte. Das ist Mumpitz. Scheint also ein Käferchen im VST zu sein. :-( Ich würde vorerst bei meiner Vermutung bleiben, dass da irgendwo im VST eine hartcodierte MainColumn = 0 verblieben ist. |
AW: TVirtualStringTree AutoFitColumns erste Spalte wird nicht angepasst
Zitat:
Delphi-Quellcode:
unit Unit2;
interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, VirtualTrees, Vcl.StdCtrls; type TMyDataSet = record Name: String; Desc: String; end; PMyDataSet = ^TMyDataSet; type TForm2 = class(TForm) vstTable: TVirtualStringTree; Button1: TButton; procedure FormCreate(Sender: TObject); procedure vstTableGetText(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType; var CellText: string); procedure Button1Click(Sender: TObject); private { Private-Deklarationen } public { Public-Deklarationen } end; var Form2: TForm2; implementation {$R *.dfm} procedure TForm2.Button1Click(Sender: TObject); var Node: PVirtualNode; Data: PMyDataSet; begin ShowMessage(IntToStr(vstTable.GetMaxColumnWidth(0, False))); //62px ShowMessage(IntToStr(vstTable.GetMaxColumnWidth(1, False))); //77px vstTable.BeginUpdate; Node := vstTable.FocusedNode; if Assigned(Node) then begin Data := vstTable.GetNodeData(Node); if Assigned(Data) then begin Data^.Name := Data^.Name + 'xyz 12345'; Data^.Desc := Data^.Desc + 'xyz 12345'; end; end; vstTable.EndUpdate; //Workaround or musst have? //vstTable.InvalidateNode(Node); ShowMessage(IntToStr(vstTable.GetMaxColumnWidth(0, False))); //62px and 106px with the "workaround" ShowMessage(IntToStr(vstTable.GetMaxColumnWidth(1, False))); //127px vstTable.Header.AutoFitColumns(False, smaAllColumns); end; procedure TForm2.FormCreate(Sender: TObject); var Node: PVirtualNode; Data: PMyDataSet; Index: Integer; begin vstTable.NodeDataSize := SizeOf(TMyDataSet); vstTable.BeginUpdate; for Index := 1 to 10 do begin Node := vstTable.AddChild(nil); Data := vstTable.GetNodeData(Node); if Assigned(Data) then begin Data^.Name := IntToStr(Index)+'. Bla bla'; Data^.Desc := 'Bla bla bla bla'; end; end; vstTable.EndUpdate; vstTable.Header.AutoFitColumns(False, smaAllColumns); end; procedure TForm2.vstTableGetText(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType; var CellText: string); var Data: PMyDataSet; begin Data := vstTable.GetNodeData(Node); if Assigned(Data) then begin case Column of 0: CellText := Data^.Name; 1: CellText := Data^.Desc; end; end; end; end. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:01 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz