![]() |
AW: VirtualTreeView Editfelder, ComboBox und andere
Hallo Aviator,
Danke erstmal. Mach Dir aktuell mal keine Arbeit. Ich habe es fast gelöst. Stelle kürzlich ein Musterprojekt ein. Eines fehlt mir aktuell noch. Im EditKeyDown, will ich mit der TAB Taste in die nächste Spalte (Column) springen und diese in den Editmode versetzen. Hierzu vermisse ich eine Methode wie NextVisibleColumn. Das selbe soll dann mit den Taste Links/Rechts passieren...
Delphi-Quellcode:
Vielleicht hat hier noch jemand nee Idee...
case Key of
TAB: begin .... end; VK_Right, VK_Left: begin ... end; Gruß Jens |
AW: VirtualTreeView Editfelder, ComboBox und andere
Zitat:
Delphi-Quellcode:
senden und im Formular mit dem VST darauf reagieren. Beim Drücken von Return schmierte das Programm nämlich mit einer AV ab, was auf den Tree zurückzuführen war und nur damit umgangen werden konnte. Wie es bei der ganz neuen Version aussieht weiß ich nicht, da ich aktuell noch die Version 5.5 verwende. Vielleicht wurde der Fehler darin ja behoben. Evtl. könntest du das auch so machen und dann beim PostMessage im Parameter den Key bzw. einen Wert mitgeben an dem du erkennst, dass du in die nächste Spalte springen willst und dort direkt wieder ein
PostMessage()
Delphi-Quellcode:
ausführst. Eine andere evtl. schönere Lösung habe ich jetzt auf Anhieb beim Schreiben nicht parat. Vielleicht würde mir da noch etwas besseres einfallen, nur hatte ich das bisher eigentlich nicht gebraucht.
BeginEdit(Node, Column)
|
AW: VirtualTreeView Editfelder, ComboBox und andere
Also das mit der "Enter" Taste funktioniert schon ganz gut.
Delphi-Quellcode:
procedure TEditEditLink.EditKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState); var ANode : PVirtualNode; begin case Key of VK_ESCAPE: begin Key := 0; end; VK_RETURN: begin FTree.InvalidateNode(FNode); if (ssShift in Shift) then ANode := FTree.GetPreviousVisible(FNode, True) else ANode := FTree.GetNextVisible(FNode, True); FTree.EndEditNode; if ANode <> nil then FTree.FocusedNode := ANode; Key := 0; if FTree.CanEdit(FTree.FocusedNode, FTree.FocusedColumn) then TVirtualStringTreeHack(FTree).DoEdit; end; VK_TAB: begin end; VK_LEFT, VK_RIGHT: begin end; VK_UP, VK_DOWN: begin FTree.InvalidateNode(FNode); if Key = VK_UP then ANode := FTree.GetPreviousVisible(FNode, True) else ANode := FTree.GetNextVisible(FNode, True); FTree.EndEditNode; if ANode <> nil then FTree.FocusedNode := ANode; Key := 0; if FTree.CanEdit(FTree.FocusedNode, FTree.FocusedColumn) then TVirtualStringTreeHack(FTree).DoEdit; end; end; end; |
AW: VirtualTreeView Editfelder, ComboBox und andere
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo zusammen,
im Anhang mal das aktuelle Musterprojekt. Das Steuern mit den Tasten "Enter", "Shift & Enter" und "Auf & Ab" funktioniert schon mal ganz gut. Auch die verschiedenen Editoren (TEdit, TComboBox) gehen. Das mit der "TAB-Taste" und den "Tasten Rechts & Links" bekomme ich allerdings nicht gelöst. Jemand eine Idee. Ansonsten wäre ich über Kommentare zum Musterprojekt dankbar. Danke schon mal, einen schönen Abend und Gruß Jens |
AW: VirtualTreeView Editfelder, ComboBox und andere
Zitat:
Delphi-Quellcode:
auf und gut ist. Sollte genauso funktionieren, nur sauberer. Habe mir das Projekt jetzt nicht runtergeladen und getestet ob es wirklich funktioniert.
FTree.EditNode(Node, Column)
Zu der Sache mit der Tab Taste vermute ich, dass das Drücken von Tab das Control verlässt und du ggf. sogar im EditMode der aktuellen Node bleibst. Hier müsstest du (wahrscheinlich im KeyPress Event) die Tab Taste abfangen, sodass diese nicht vom System weiterverarbeitet wird. |
AW: VirtualTreeView Editfelder, ComboBox und andere
Delphi-Quellcode:
Hab ich angepasst. Das mit dem Hack, habe ich aus einem Lazarus Forum. if FTree.CanEdit(FTree.FocusedNode, FTree.FocusedColumn) then FTree.EditNode(FTree.FocusedNode, FTree.FocusedColumn); Die TAB Taste, bekomme ich aber auch nicht im KeyPress abgefangen. |
AW: VirtualTreeView Editfelder, ComboBox und andere
Also das Ding bringt mich noch zur Verzweiflung. Es muss doch möglich sein, eine Komponente wie das VST mit der Tastatur annähernd wie Excel bedienen zu können.
Das mit dem "Enter" führt übrigens mittlerweile (nach dem Übernehmen der Daten in den Node) auch zu einer Exception. Hier mal der aktuelle Editor...
Delphi-Quellcode:
Ich will ja eigendlich nur folgende Funktionen:
unit TreeEditors;
interface uses VirtualTrees, Vcl.StdCtrls, Winapi.Windows, System.SysUtils, Winapi.Messages, System.Classes, Vcl.Controls, Vcl.Forms, Vcl.Dialogs; //Eigener Type für die verschiedenen Editfelder ( type TEditValueType = (evtNone { Kein Editiern möglich }, evtNumber { Nur Zahlen - Ein TEdit mit "NumbersOnly = true }, evtString { Text - Ein TEdit }, evtPickString { Text mit fester Auswahlmöglichkeit - TComboBox } ); //Eigene Klasse zur Haltung der Daten type TOMyClass = class private FAInt : integer; //Spalte 1 im VST - eine Zahl FAPickString : string; //Spalte 2 im VST - Eine Text mit fester Auswahlmöglichkeit FAString : string; //Spalte 3 im VST - Eine Text FBString : string; //Spalte 4 im VST - Eine Text FBPickString : string; //Spalte 5 im VST - Eine Text mit fester Auswahlmöglichkeit public property AInt: integer read FAInt write FAInt; property APickString : string read FAPickString write FAPickString; property AString : string read FAString write FAString; property BString : string read FBString write FBString; property BPickString : string read FBPickString write FBPickString; end; //Der Datenrecord für das VST type PMyData = ^TMyData; TMyData = record FValueType: array[0..4] of TEditValueType; //Die Var für den Typ des Editierfeld FObject : TObject; //Das Objekt der Daten FChanged : Boolean; end; //Die Interface-Klasse für den Editor type TEditEditLink = class (TInterfacedObject, IVTEditLink) private FEdit: TWinControl; //FEdit als TWinControl für die verschiedenen Editormöglichkeiten (TEdit, TComboBox etc.) FTree : TVirtualStringTree; //Das VST FNode : PVirtualNode; //Das Node FColumn : Integer; //Der Column protected procedure EditKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); //Für die Steuerung der Editorfelder über Tastatur procedure EditKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState); //Für die Steuerung der Editorfelder über Tastatur public destructor Destroy; override; //Zur Freigabe der Editor-Controls beim beenden function BeginEdit: Boolean; virtual; stdcall; //Start Editorvorgang function CancelEdit: Boolean; virtual; stdcall; //Abbruch Editorvorgang function EndEdit: Boolean; virtual; stdcall; //Ende Editorvorgang function GetBounds: TRect; virtual; stdcall; //Größe ermitteln function PrepareEdit(Tree: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex): Boolean; stdcall; //Erstellen der jeweiligen Editor - Controls procedure ProcessMessage(var Message: TMessage); virtual; stdcall; //Für die Übergabe der Nachrichten des VST an den Editor procedure SetBounds(R: TRect); stdcall; //Größe der Editorfelder setzen end; implementation uses fMain; { TEditEditLink } function TEditEditLink.BeginEdit: Boolean; begin //Prüfung um welches Control es sich handelt und entsprechend aktivieren if FEdit is TEdit then begin FEdit.Show; //Anzeigen FEdit.SetFocus; //Focus zuweisen TEdit(FEdit).SelectAll; //Text im TEdit komplett selektieren end else if FEdit is TComboBox then begin FEdit.Show; //Anzeigen FEdit.SetFocus; //Focus zuweisen TComboBox(FEdit).SelectAll; //Text im TEdit komplett selektieren end; end; function TEditEditLink.CancelEdit: Boolean; begin Result := True; //Abbruch erfolgt FEdit.Hide; //Control auf Visible false end; destructor TEditEditLink.Destroy; begin FEdit.Free; //Control nach beenden des Editors wieder freigeben inherited; end; procedure TEditEditLink.EditKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); var ANode : PVirtualNode; CanAdvance : Boolean; AColumn : TColumnIndex; begin case Key of VK_ESCAPE: begin Key := 0; end; VK_RETURN: begin if FEdit is TEdit then begin FTree.InvalidateNode(FNode); if (ssShift in Shift) then ANode := FTree.GetPreviousVisible(FNode, True) else ANode := FTree.GetNextVisible(FNode, True); FTree.EndEditNode; if ANode <> nil then FTree.FocusedNode := ANode; Key := 0; if FTree.CanEdit(FTree.FocusedNode, FTree.FocusedColumn) then FTree.EditNode(FTree.FocusedNode, FTree.FocusedColumn); end else if FEdit is TComboBox then begin FTree.InvalidateNode(FNode); if (ssShift in Shift) then ANode := FTree.GetPreviousVisible(FNode, True) else ANode := FTree.GetNextVisible(FNode, True); FTree.EndEditNode; if ANode <> nil then FTree.FocusedNode := ANode; Key := 0; if FTree.CanEdit(FTree.FocusedNode, FTree.FocusedColumn) then FTree.EditNode(FTree.FocusedNode, FTree.FocusedColumn); end; end; VK_TAB: begin end; VK_LEFT, VK_RIGHT: begin end; VK_UP, VK_DOWN: begin if FEdit is TEdit then begin FTree.InvalidateNode(FNode); if Key = VK_UP then ANode := FTree.GetPreviousVisible(FNode, True) else ANode := FTree.GetNextVisible(FNode, True); FTree.EndEditNode; if ANode <> nil then FTree.FocusedNode := ANode; Key := 0; if FTree.CanEdit(FTree.FocusedNode, FTree.FocusedColumn) then FTree.EditNode(FTree.FocusedNode, FTree.FocusedColumn); end else if FEdit is TComboBox then begin TComboBox(FEdit).DroppedDown := True; end; end; end; end; procedure TEditEditLink.EditKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState); begin case Key of VK_ESCAPE: begin FTree.CancelEditNode; Key := 0; end; end; end; function TEditEditLink.EndEdit: Boolean; var Data: PMyData; Buffer: array[0..1024] of Char; S: UnicodeString; I: Integer; begin Result := True; Data := FTree.GetNodeData(FNode); case FColumn of 0: begin S := TEdit(FEdit).Text; if S <> IntToStr(TOMyClass(Data.FObject).FAInt) then begin TOMyClass(Data.FObject).FAInt := StrToInt(S); Data.FChanged := True; end; end; 1: begin S := TComboBox(FEdit).Text; if S <> TOMyClass(Data.FObject).FAPickString then begin TOMyClass(Data.FObject).FAPickString := S; Data.FChanged := True; end; end; 2: begin S := TEdit(FEdit).Text; if S <> TOMyClass(Data.FObject).FAString then begin TOMyClass(Data.FObject).FAString := S; Data.FChanged := True; end; end; 3: begin S := TEdit(FEdit).Text; if S <> TOMyClass(Data.FObject).FBString then begin TOMyClass(Data.FObject).FBString := S; Data.FChanged := True; end; end; 4: begin S := TComboBox(FEdit).Text; if S <> TOMyClass(Data.FObject).FBPickString then begin TOMyClass(Data.FObject).FBPickString := S; Data.FChanged := True; end; end; end; if Data.FChanged then begin FTree.InvalidateNode(FNode); { z.B. zusätzlich Update Datenbank } end; FEdit.Hide; end; function TEditEditLink.GetBounds: TRect; begin Result := FEdit.BoundsRect; //Größe ermitteln end; function TEditEditLink.PrepareEdit(Tree: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex): Boolean; var Data: PMyData; FValueType : TEditValueType; begin Result := True; FTree := Tree as TVirtualStringTree; FNode := Node; FColumn := Column; FEdit.Free; FEdit := nil; Data := FTree.GetNodeData(FNode); FValueType := Data.FValueType[FColumn]; case FValueType of evtNumber: begin FEdit := TEdit.Create(FTree); TEdit(FEdit).OnKeyDown := EditKeyDown; TEdit(FEdit).OnKeyUp := EditKeyUp; TEdit(FEdit).Text := IntToStr(TOMyClass(Data.FObject).FAInt); FEdit.Visible := False; FEdit.Parent := FTree; end; evtString: begin FEdit := TEdit.Create(FTree); TEdit(FEdit).OnKeyDown := EditKeyDown; TEdit(FEdit).OnKeyUp := EditKeyUp; case FColumn of 2: TEdit(FEdit).Text := TOMyClass(Data.FObject).FAString; 3: TEdit(FEdit).Text := TOMyClass(Data.FObject).FBString; end; FEdit.Visible := False; FEdit.Parent := FTree; end; evtPickString: begin FEdit := TComboBox.Create(FTree); TComboBox(FEdit).OnKeyDown := EditKeyDown; TComboBox(FEdit).OnKeyUp := EditKeyUp; FEdit.Visible := False; FEdit.Parent := FTree; case FColumn of 1: begin TComboBox(FEdit).Text := TOMyClass(Data.FObject).FAPickString; TComboBox(FEdit).Items.Add('Listenauswahl Text 1'); TComboBox(FEdit).Items.Add('Listenauswahl Text 2'); TComboBox(FEdit).Items.Add('Listenauswahl Text 3'); TComboBox(FEdit).Items.Add('Listenauswahl Text 4'); TComboBox(FEdit).Items.Add('Listenauswahl Text 5'); end; 4: begin TComboBox(FEdit).Text := TOMyClass(Data.FObject).FBPickString; TComboBox(FEdit).Items.Add('Zweite Auswahl Text 1'); TComboBox(FEdit).Items.Add('Zweite Auswahl Text 2'); TComboBox(FEdit).Items.Add('Zweite Auswahl Text 3'); end; end; end else begin Result := False; end; end; end; procedure TEditEditLink.ProcessMessage(var Message: TMessage); begin if Assigned(FEdit) then FEdit.WindowProc(Message); end; procedure TEditEditLink.SetBounds(R: TRect); var Dummy : Integer; begin FTree.Header.Columns.GetColumnBounds(FColumn, Dummy, R.Right); R.Left := Dummy;// + FTree.Margin * 2; FEdit.Width := R.Width; R.Bottom := Abs(R.Top) + Abs(FTree.NodeHeight[FTree.FocusedNode]); InflateRect(R, 0, 1); FEdit.BoundsRect := R; end; end. VK_ENTER - eine Zeile nach unten VK_ENTER/SHIFT - eine Zeile nach oben VK_TAB -eine Spalte nach Links VK_TAB/Shift - eine Spalte nach Rechts VK_UP - eine Zeile nach oben VK_DOWN - eine Zeile nach unten VK_LEFT - eine Spalte nach links VK_RIGHT - eine Spalte nach links |
AW: VirtualTreeView Editfelder, ComboBox und andere
Zitat:
![]() Zitat:
|
AW: VirtualTreeView Editfelder, ComboBox und andere
Zitat:
|
AW: VirtualTreeView Editfelder, ComboBox und andere
Liste der Anhänge anzeigen (Anzahl: 2)
Hallo Jens...:P
Um dir weiteren Frust zu ersparen hätte ich noch einen Alternativvorschlag. Wenn es denn nicht unbedingt die "im Grid editiererei" sein muß kannst du auch folgendes probieren. (Siehe Bild) 1. Die Reihen im Grid (hier Listview) sind quasi immer Readonly. 2. Zum Editieren ein Fenster ohne Rahmen modal auf die Zeile legen. -> Das Editieren kann nur definiert verlassen werden (Save oder Abbruch). 3. Im Design ist man völlig unabhängig von der Grideinteilung obwohl man z.B. die obere Zeile dem Grid nachempfinden kann. 4. So lassen sich auch komplexe Datenobjekte, welche an dem Listeneintrag hängen, bearbeiten ohne massig Spalten zu haben. 5. Man kann auf einer "Kopie" des Datenobjektes arbeiten und nur beim Save die Informationen übertragen. ...was vergessen? :gruebel: Nö. :P doch: 6. Man kann alle Vorzüge eines Formulares nutzen incl. Tab Reihenfolgen, ENTER zum nächsten Control etc. 7. Die Editoren erben alle von einem Basiseditor mit den Basisfunktionalitäten, Events etc. und Buttons. 8. Irgendwann willst du ein anderes Control benutzen...kein Problem. Der Editor bleibt was er ist. :zwinker: |
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:16 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-2025 by Thomas Breitkreuz