![]() |
Stringgrid selection Problem !
Hi leute,
hab ein großes Problem, nachdem ich beim coden so richtig in fahrt gekommen bin, musste ich leider feststellen,das das Stringgrid so bloede markiert, immer nur ein viereckiger bereich, ich MUSS es aber so hinkriegen, das das stringgrid so markiert wie ein Memo oder Richedit, sonst waren zweieinhalb Wochen Arbeit umsonst, und ehrlich gesagt wuerde ich das Project eher hinschmeissen als komplett von vorn anzufangen. also bitte , sagt mir man kann den markierungsmodus vom grid umschalten ich hoffe wirklich jemand kann mir weiterhelfen :pale: |
Re: Stringgrid selection Problem !
Liste der Anhänge anzeigen (Anzahl: 1)
Erst einmal die schlechte Nachricht :mrgreen:
TStringGrid kann es nicht, genauso wie auch das TDrawGrid von Delphi. Die Ursache hier liegt etwas tiefer begraben. Das Delphi-Grid merkt sich ausschließlich das markierte Rechteck in der Eigenschaft Selection
Delphi-Quellcode:
Daran lässt sich auch erkennen, daß sich dieses nicht ohne weiteres umgehen lässt. Nun gibt es zwei grundlegende Möglichkeiten. Die erste wäre die Nutzung einer anderen Komponente, was schnell zu Problemen führen kann, die zweite ist es, das Verhalten des StringGrids etwas abzuändern :-)
type
TGridRect = record case Integer of 0: (Left, Top, Right, Bottom: Longint); 1: (TopLeft, BottomRight: TGridCoord); end; TCustomGrid = class(TCustomControl) ... property Selection: TGridRect read GetSelection write SetSelection; ... end; Anbei mal ein ScreenShot des geänderten StringGrid. Nachteilig an dieser Lösung ist, daß das Normale Verhalten des StringGrid (auswahl über Maus, Shift+Cursor) nicht mehr geht, außer Du nimmst Dich dieses Problemes an und änderst das auch noch - mir fehlt jetzt die Zeit. Mehr in ein paar Minuten. ...:cat:... |
Re: Stringgrid selection Problem !
So, die Lösung habe ich gleich in die CodeLib befördert. Hier:
![]() Viel Erfolg. Wenn Du Fragen hast, bitte in Deinem (diesen!) Thread. Danke. ...:cat:... |
Re: Stringgrid selection Problem !
hallo sakura,
habe mir dein screenshot angesehen, und ich glaube du hast mich falsch verstanden, (oder ich verstehen dein screeshot falsch). ich will keine multiselectionen haben, ich will nur, das wenn ich in die mitte einer zeile mit der makierung anfange, und z.b. eine zeile runter gehe, die markierung wieder bis zur mitte der zeile geht ->> kein rechteckiger bereich was ich bei dir gesehen hab, waren doch multiselectierte bereiche oder ?? |
Re: Stringgrid selection Problem !
Zitat:
...:cat:... |
Re: Stringgrid selection Problem !
Liste der Anhänge anzeigen (Anzahl: 1)
hi sakura,
also ich hab mal ein screenshot beigefügt, zu sagen waere noch , das ich das grid manuell mit daten gefuettert habe, die zellen sind also nicht mit irgendeiner festgelegten datenbankstruktur verknuepft, sondern mit einem array, gibt also keinen grund, warum ich nur rechteckig markieren sollte :) zum screenshoot: stelle dir einfach vor, die buchstaben seien einzelne zellen, und ich will immer nur einen zusammenhaegenden bereich , kein multiselekt! Die hoffnung stirbt zuletzt, danke für deine hilfe :| |
Re: Stringgrid selection Problem !
Okay, verstanden und ... ;) gelöst.
Das ist schon etwas einfacher. Du mußt zwei Ereignisse abfangen. Einmal das OnSelectCell, um dem StringGrid mitzuteilen, daß sich die Auswahl grundlegend geändert hat, und einmal das OnDrawCell Ereigniss, um die Auswahl darzustellen. Außerdem habe ich noch eine Methode geschrieben, welche ermittelt, ob sich eine Zelle (Spalte, Zeile) in der erweiterten Auswahl befindet. Hier die drei Methoden und es geht.
Delphi-Quellcode:
...:cat:...
type
TForm1 = class(TForm) [...] private { Private declarations } function CellInRange(aGrid: TCustomDrawGrid; aCol, aRow: Integer): Boolean; [...] end; // testen, ob sich eine bestimmte Zelle in der erweiterten Auswahl aufhält function TForm1.CellInRange(aGrid: TCustomDrawGrid; aCol, aRow: Integer ): Boolean; begin Result := False; if aRow < aGrid.Selection.Top then Exit; if aRow = aGrid.Selection.Top then if aCol < aGrid.Selection.Left then Exit; if aRow > aGrid.Selection.Bottom then Exit; if aRow = aGrid.Selection.Bottom then if aCol > aGrid.Selection.Right then Exit; Result := True; end; // die Ereignisroutinen procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer; Rect: TRect; State: TGridDrawState); begin if Sender = nil then Exit; if not (Sender is TStringGrid) then Exit; with Sender as TStringGrid do begin // skip fixed columns if (ACol < FixedCols) or (ARow < FixedRows) then Exit; // select color if CellInRange(Sender as TStringGrid, ACol, ARow) then begin // selected cell Canvas.Brush.Color := clHighlight; Canvas.Font.Color := clHighlightText; end else begin // cell not selected Canvas.Brush.Color := clWindow; Canvas.Font.Color := clWindowText; end; // draw cell Canvas.TextRect(Rect, Rect.Left, Rect.Top, Cells[ACol, ARow]); end; end; procedure TForm1.StringGrid1SelectCell(Sender: TObject; ACol, ARow: Integer; var CanSelect: Boolean); begin if Sender = nil then Exit; if not (Sender is TStringGrid) then Exit; with Sender as TStringGrid do begin Update; Invalidate; end; end; |
Re: Stringgrid selection Problem !
mahlzeit,
also dein code funktioniert bei mir nich, habs mal gerade in einem testproject getestet (neue form und nur 1 stringgrid) macht nicht das was es soll, entweder ist der code fehlerhaft, oder wir reden aneinander vorbei. es muss so sein: wenn du z. b. die markierung in der mitte von zeile 1 anfaengst , und gehst nach zeile 3. dann ist die rechte haelfte von zeile 1 markiert, die komplette zeile 2 und die linke haelfte von zeile 3 muss so sein weil eindimensionales array(werte alle hintereinander); aber stringgrid stellt zu 32 col breite dar, dann gehts weiter in naechster zeile arrayposotion berechet sich folgendermaßen: (acol)+(arow * 32) verstehst du, ich muss sozusagen wenn ich eine zeile runter gehe beim markieren, alle zellen die zwischen erster und letzter sind markieren koennen, um alle korrekten arraypositionen zu erhalten ich hoffe ich habs dir jetz richtig erklaeren koennen |
Re: Stringgrid selection Problem !
Genauso lief der Code auch bei mir. Was für eine Delphiversion hast Du denn? Hast Du das OnSelectCell Ereignis eingesetzt?
...:cat:... |
Re: Stringgrid selection Problem !
Liste der Anhänge anzeigen (Anzahl: 1)
mahlzeit,
also habs nochmal getestet. beide ereignisse sind gesetzt, onselectcell und ondrawcell wenn ich markiere, zeichet er ein rechteck von linksoben nach rechstunten. ich kann zwar wenn ich rechtsunten die maus nach links bewege zellen abwaehlen, aber das is nich das was ich brauche. er selectiert , die rows ZWISCHEN 1 markierter zeile und letzter markierter zeile nicht vollstaendig, sondern nur ab der col position, die ich hab, wenn ich die markierung beginne. ich glaub du hast mich doch nicht verstanden mach dir mal ne leere form, memo drauf, ausfuehren, bisserl text reinschreiben oder kopieren, idealerweise gleichlange zeilen, und dann guck dir mal an wie memo markiert. schicke dir auch mein testproject , was ich zum testen deines codes nutze, vielleicht hab ich ja auch einen fehler drin :( |
Re: Stringgrid selection Problem !
Liste der Anhänge anzeigen (Anzahl: 1)
:hi: Richard
Hab mal ein Bildchen angehängt. Willst Du sowas in der Art? mfg Tobias |
Re: Stringgrid selection Problem !
halli Miri! : :-D
ja, ja, jaaaaaaaaaaa , genau so will ich das haben wie haste das gemacht ????? Ps: kannste mir vielleicht ma dein testproject schicken, von dem du denn screenshot gemacht hast, das sieht ziemlich nuetzlich aus mit den cellpositionen :dance: |
Re: Stringgrid selection Problem !
:hi:
Es ist eben noch nicht so perfekt :oops: :mrgreen: Ich poste Dir den Code wenns besser läuft. Ok? mfg Tobias |
Re: Stringgrid selection Problem !
@richard_boderich
Na ja, den kleinen Bug in meiner Lösung hättest Du ja auch selbst entfernen können :mrgreen: Einfach mal die Methode CellInRange austauschen.
Delphi-Quellcode:
...:cat:...
function TForm1.CellInRange(aGrid: TCustomDrawGrid; aCol, aRow: Integer
): Boolean; var Dummy, StartPoint, EndPoint: TGridCoord; begin Result := False; StartPoint.X := aGrid.Col; StartPoint.Y := aGrid.Row; if aGrid.Selection.Left <> StartPoint.X then EndPoint.X := aGrid.Selection.Left else EndPoint.X := aGrid.Selection.Right; if aGrid.Selection.Top <> StartPoint.Y then EndPoint.Y := aGrid.Selection.Top else EndPoint.Y := aGrid.Selection.Bottom; if StartPoint.Y > EndPoint.Y then begin Dummy := StartPoint; StartPoint := EndPoint; EndPoint := Dummy; end; if aRow < StartPoint.Y then Exit; if aRow = StartPoint.Y then if aCol < StartPoint.X then Exit; if aRow > EndPoint.Y then Exit; if aRow = EndPoint.Y then if aCol > EndPoint.X then Exit; Result := True; end; |
Re: Stringgrid selection Problem !
hi miri,
ja, ok machma so. :cheers: ist deine loesung sauber programmiert, oder sind da irgentwelche dirty tricks drin ?? gib mir mal n ansatz, dann kann ich selber proggen, weil komme ohne das nich weiter :wink: |
Re: Stringgrid selection Problem !
Und meine Lösung :cry: Die ist jetzt doch sauber und sollte gehen :cry:
...:cat:... |
Re: Stringgrid selection Problem !
:hi: Richard,
Nimm Sakuras Variante, er hat etwa das selbe gemacht wie ich und es funktioniert. mfg Tobias [Edit] :gruebel: nachdem ich meine Source gelöscht habe funktioniert dein Code auch nicht mehr ^^ [/Edit] |
Re: Stringgrid selection Problem !
hallo sakura,
hab grad nochmal deinen neuen code getestet, funktioniert auch nicht !!! haste das aus dem gedaechtnis geschrieben oder getestet ? wenn du es getestet hast, dann hast mein problem nich verstanden, aber ich danken trotzdem für deine hilfe :) |
Re: Stringgrid selection Problem !
Zitat:
Zitat:
Jetzt werden doch alle Felder von x1,y1 ... x2,y2 horizontal markiert. Was ist denn noch nicht so wie Du es erwartest :gruebel: ...:cat:... |
Re: Stringgrid selection Problem !
Okay, einen Fehler habe ich noch gefunden:
Code:
...:cat:...
function TForm1.CellInRange(aGrid: TCustomDrawGrid; aCol, aRow: Integer
): Boolean; var Dummy, StartPoint, EndPoint: TGridCoord; begin Result := False; StartPoint.X := aGrid.Col; StartPoint.Y := aGrid.Row; if aGrid.Selection.Left <> StartPoint.X then EndPoint.X := aGrid.Selection.Left else EndPoint.X := aGrid.Selection.Right; if aGrid.Selection.Top <> StartPoint.Y then EndPoint.Y := aGrid.Selection.Top else EndPoint.Y := aGrid.Selection.Bottom; [color=#f50000][s]if StartPoint.Y > EndPoint.Y then[/s] if (StartPoint.Y > EndPoint.Y) or ((StartPoint.Y = EndPoint.Y) and (StartPoint.X > EndPoint.X)) then[/color] begin Dummy := StartPoint; StartPoint := EndPoint; EndPoint := Dummy; end; if aRow < StartPoint.Y then Exit; if aRow = StartPoint.Y then if aCol < StartPoint.X then Exit; if aRow > EndPoint.Y then Exit; if aRow = EndPoint.Y then if aCol > EndPoint.X then Exit; Result := True; end; P.S.: Wenn es das nicht ist, dann solltest Du noch einmal von Grund auf erklären was Du eigentlich willst :gruebel: |
Re: Stringgrid selection Problem !
Hm, keine Antwort ist auch eine Antwort :? Aber, für den Fall, daß Du mit der Maus selektierst, so ist mir aufgefallen, mußt Du noch folgende Events füllen: OnMouseMove, OnMouseDown, OnMouseUp
Delphi-Quellcode:
Desweiteren muss die Variable FMouseSelects: Boolean; im Form deklariert werden.
procedure TForm1.StringGrid1MouseDown(Sender: TObject;
Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin if Sender = nil then Exit; if not (Sender is TStringGrid) then Exit; FMouseSelects := True; end; procedure TForm1.StringGrid1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); begin if Sender = nil then Exit; if not (Sender is TStringGrid) then Exit; if not FMouseSelects then Exit; with Sender as TStringGrid do begin Update; Invalidate; end; end; procedure TForm1.StringGrid1MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin if Sender = nil then Exit; if not (Sender is TStringGrid) then Exit; FMouseSelects := False; end; ...:cat:... |
Re: Stringgrid selection Problem !
Liste der Anhänge anzeigen (Anzahl: 1)
Noch mal ich :mrgreen: Ich habe das Sample vergessen :roll:
...:cat:... |
Re: Stringgrid selection Problem !
ok sakura,
also ich versuchs jetz nochmal zu erklaeren, deine routiene lauft nich, ich denke aber das du das falsche meinst ich versuchs jetz mal anders ,ok also : 1. wenn mouse down im stringgrid , dann schaue in welcher zeile (row a) du bist und selectiere alle felder von aktuellem colwert bis colcount vom stringgrid (erste zeile) 2. wenn mousemove bzw. mouse up, dann schaue in welcher zeile (row b) du bist , wobei (row b > row a sein muss) und selectiere alle felder von 0 bis colwert (letzte zeile); 3. und dann selectiere auch noch das rechteck dazwischen (0,rowa+1) zu (colcount,rowb-1) (rechteckiger bereich) markierung sieht dann so aus: #=markiert
Delphi-Quellcode:
Ps: ich denke dein code kann nicht funktionieren weil denkfehler , weil der selectmode des stringgrid noch mit aktiv ist
0000000#################### -> erste zeile
########################### -> [rechteckiger bereich zwischen...] ########################### -> [...zeile 1 und letzter zeile....] ########0000000000000000000 -> letzte zeile 000000000000000000000000000 000000000000000000000000000 000000000000000000000000000 wenn du naenlich beim markieren nur eine zeile nach unten gehst, dann selectiert , das grid bei deiner routine auch die 2 zeile von der colposition an und nicht von 0 wie in der darstellung oben, eventueller Loesungsweg: bei grid option: rangeselect auf false und markierung komplett selber zeichnen hoffe jetz , das du mich verstehst |
Re: Stringgrid selection Problem !
hallo sakura,
dein beispiel lauft jetzt richtig, muss daran gelegen haben, das ich immer versucht hab mit der maus zu selektieren ,allerdings ist da ein unschoenes grafisches zucken des markierten bereichs,wenn man die maus beim markieren bewegt, gibst ne moeglichkeit , das noch zu verbessern ? :) :zwinker: |
Re: Stringgrid selection Problem !
Zitat:
...:cat:... |
Re: Stringgrid selection Problem !
Das ist typischer borland mist, jetz kann ich 70 prozent meines codes wegschmeissen
und von vorn anfangen. bloede oop, da war turbo pascal um laengen besser, wenn die wenigstens in erwaegung gezogen hatten , ne eigenschaft "selectmode" für die dämliche stringgrid kompo zu machen in der ich den selektionsstil waehlen hatte koennen, aber nee.. was nutzt es wenn du in 2 min den code zusammenklicken kannst, und dann bei solch simplen dingen passen must. auf der anderen seite hatte ich schon mal faelle, in dehnen ich 2 tage gesaessen hab , um die nichterwuenschten funktionen und deren verhalten in kompos rueckgaengig zu machen, was ist den das fuer ne logic, laenger damit zuzubringen unerwuenschte verhalten zu unterdrueckten, als sich dem eingentlichen problem zu widmen! ich kann dazu nur sagen : :kotz: so und wenn ihr mich jetz aus dem forum schmeissen wollt, is mir das jetz auch egal |
Re: Stringgrid selection Problem !
:hi:
Dann wünsch ich dir viel Spass in der ![]() Die VCL ist nicht perfekt, aber sie nimmt einem eine Menge Arbeit ab. Schau sonst mal noch auf ![]() Und in der ![]() mfg Tobias |
Re: Stringgrid selection Problem !
hacke den tread mal ab,
antwortet sowieso keiner mehr |
Re: Stringgrid selection Problem !
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:
Zitat:
Delphi-Quellcode:
wirkt hier Wunder.
StringGrid.DoubleBuffered := true;
Ich hab außerdem auch mal ein bisschen mit dem StringGrid rumgespielt und eine andere Lösung entwickelt. Benötigt zwar auch das DoubleBufferd, wirkt aber für mich insgesamt ein bisschen weniger hakelig als Sakuras Variante (die ich hier keinesfalls schlecht machen will :angle2: ). Projekt im Anhang. [EDIT]Fehler im Attachment ausgebessert[/EDIT] |
Re: Stringgrid selection Problem !
hi Niko,
was bewirkt den die anweisung double buffer genau ? und warum ist sie unschoen ??? hab grad dein file geladen,will gleich ma probieren :-D nochmal vielen dank, waere toll wenn es wirklich hilft |
Re: Stringgrid selection Problem !
Zitat:
...:cat:... P.S.: Gegen Double-Buffered ist nichts einzuwenden - nur was hat bei meiner Lösung gehakt :gruebel: |
Re: Stringgrid selection Problem !
mensch Niko, altes haus , dat funktioniert, also , wenn ich nich ganz genau wüsst, das ich hetero wär,
dann würd ich dich jetz küssen! :wink: ok leutz, jetz is party angesagt ! :lol: :dancer2: :cheers: :bounce2: :witch: :hello: :party: :dancer: :witch: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :dance: :spin: :corky: :party: :dp: :zwinker: :lol: los niko ab auf die tanzflaeche !!!!! |
Re: Stringgrid selection Problem !
Danke, man hilft wo man kann :mrgreen:
Zitat:
Zitat:
Ich muss aber zugeben, dass meine Variante das Markieren mit der Tastatur nicht unterstützt - lässt sich aber nachrüsten, wenn nötig. |
Re: Stringgrid selection Problem !
Zitat:
...:cat:... |
Re: Stringgrid selection Problem !
servus nico,
eine frage noch an dich, ich muss unbedingt noch von jeder selektierten celle die col und row werte haben, da ich aus col und row position den indexwert eines arrays berechne, an welcher stelle in deinem code kann ich das tun, ohne irgentwelche anderen effekte auszuloesen??? ich hab dann vor die gelieferten indexwerte irgendwie zwischenzuspeichern, um dann arraybereiche kopieren zu koennen ! arrayposotion berechet sich folgendermaßen: (acol)+(arow * 32) |
Re: Stringgrid selection Problem !
Auslesen (und auch Setzen) kannst du die Markierung überall - Seiteneffekte sollte es dabei nicht geben.
Wichtig ist nur, dass du die Variable Form1.GridSelection verwendest (siehe Kommentar im Code); diese ersetzt sozusagen die Selection-Eigenschaft des StringGrids. GridSelection.TopLeft enthält die Koordinaten der ersten markierten Zelle von oben und GridSelection.BottomRight die der letzten markierten. Außerdem solltest du noch zwei Zeilen am Ende von OnMouseMove ergänzen, die ich versehentlich gelöscht habe :oops: :
Delphi-Quellcode:
// ...
else with GridSelection do begin Bottom := GridSelStart.Y; Right := GridSelStart.X; Top := Row; Left := Col; end; GridOldCoord.X := Col; // ergänzen GridOldCoord.Y := Row; // ergänzen StringGrid1.Refresh; end; |
Re: Stringgrid selection Problem !
alles klar, dank dir !
nochmal vielen dank! :mrgreen: |
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:14 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