AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

tStringGrid und In-Place-Editor Problem

Ein Thema von BoolString · begonnen am 2. Aug 2010 · letzter Beitrag vom 18. Aug 2010
Antwort Antwort
BoolString

Registriert seit: 2. Feb 2009
Ort: Varel
70 Beiträge
 
RAD-Studio 2009 Pro
 
#1

AW: tStringGrid und In-Place-Editor Problem

  Alt 7. Aug 2010, 14:13
Sorry, daß meine Antwort so lange gedauerthat. Hab im schwedischen Nirgendwo gesessen und ein sporadisch aufploppends WLAN genutzt. Bin aber inzwischen wieder da...


@ibp
Danke für den Hinweis. Ich bin selbst schon einmal über auf den Link gestoßen; habe aber ob der Vielzahl von käuflich erwerbbaren StringGrid Komponenten damals etwas den Überblick verloren. Inzwischen habe ich mir das Manual runtergeladen und bin doch von der Mächtigkeit etwas angetan. Habe die gut 200 Seiten zwar bisher nur überflogen. Aber auf lange Sicht scheint das eine Option zu sein.
Mir geht es hier aber auch ein wenig darum zu lernen wie man diesen verflixten InplaceEditor richtig anspricht. Ich verstehe solche Sachen ehrlich gesagt am Besten, wenn ich Code dazu habe; bin inzwischen etwas eingerostet und begreife an Hand der aufgezeigten Herangehensweise dann doch etwas schneller

@plusplus
Ganz klar ist mir noch nicht wie du das Edit ansprichst. Ich denke mal, daß du nicht so eine oben im Formular gelagerte Eingabezeile wie unter Excel meinst. Bohrst du dann das Create auf und schickst ein Destroy beim onExit los? Hast du da evtl. ein paar Zeilen Quelltext?


Ich habe gerade (relativ vergeblich) versucht mit einem eigenen (KlassenCracker-)StringGrid eine entsprechende Funktionalität zu erzeugen. Aber irgendwie brachte das auch nicht den gewünschten Erfolg. Zudem ist es auch ein kleines Monster geworden:

Delphi-Quellcode:
type
 tTrickGrid = class;
 tExitCellEvent = Procedure (Sender: tTrickGrid; aCol, aRow: Integer; const edittext: string) of object;


  tTrickGrid = class (tStringGrid)
  private
    FExitCell : TExitCellEvent;
  protected
    Function CreateEditor: TInplaceEdit; override;
    Procedure ExitCell (const edittext: String; aCol, aRow: Integer); virtual;
  public
    property InplaceEditor;
  published
    property OnExitCell: TExitCellEvent read FExitCell write FExitCell;
  end;


  TForm1 = class (TForm)
    StringGrid1: TStringGrid;
    procedure StringGrid1GetEditText(Sender: TObject; ACol, ARow: Integer;
      var Value: string);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}


type

  tTrickInplaceEditor = class (tInplaceEdit)
  private
    FLastCol, FLastRow: Integer;
    procedure WMKillFocus(var msg: TMessage); message WM_KILLFOCUS;
    procedure WMSetFocus(var msg: TMessage); message WM_SETFOCUS;
  public
  end;


// ----------------------------------------------------------tTrickInplaceEditor

procedure tTrickInplaceEditor.WMKillFocus (Var msg: TMessage);
begin
  tTrickGrid(Grid).ExitCell (Text, FLastCol, FLastRow);
  inherited;
end;


procedure tTrickInplaceEditor.WMSetFocus (Var msg: TMessage);
begin
  FLastCol := tTrickGrid (Grid).Col;
  FLastRow := tTrickGrid (Grid).Row;
  inherited;
end;


// -------------------------------------------------------------------tTrickGrid
Function tTrickGrid.CreateEditor: tInplaceEdit;
begin
  result := tTrickInplaceEditor.Create (Self);

end;


procedure tTrickGrid.ExitCell (Const EditText: String; aCol, aRow: Integer);
begin
  If Assigned (fExitCell) THen
  Begin
    fExitCell (Self, aCol, aRow, EditText);
    fExitCell (Self, 0, 0, EditText);
  end;
end;

// -------------------------------------------------------------------StringGrid


procedure TForm1.StringGrid1GetEditText(Sender: TObject; ACol, ARow: Integer;
  var Value: string);
begin
// tTrickGrid (StringGrid1).SetEditText (aCol, aRow, Value);
// tTrickGrid (StringGrid1).CreateEditor;
end;


Vielleicht kann mir ja jemand hierbei noch einmal erklären, wie ich meinen Gedankengang sortieren müsste, damit so etwas funktioniert...

Beste Grüße

Jan
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.314 Beiträge
 
Delphi 12 Athens
 
#2

AW: tStringGrid und In-Place-Editor Problem

  Alt 7. Aug 2010, 14:20
Wie wäre es mit Delphi-Referenz durchsuchenOnGetEditText und Delphi-Referenz durchsuchenOnSetEditText?
Ein Therapeut entspricht 1024 Gigapeut.
  Mit Zitat antworten Zitat
BoolString

Registriert seit: 2. Feb 2009
Ort: Varel
70 Beiträge
 
RAD-Studio 2009 Pro
 
#3

AW: tStringGrid und In-Place-Editor Problem

  Alt 7. Aug 2010, 14:42
Hallo himitsu,

mein Problem ist, daß ich gerne in 2 StringGrids den gleichen Inhalt haben möchte. Eines ist relevant, eines ist eine reduzierte Darstellung (gerundete Werte). Wenn ich mit GetText den Zellinhalt aus dem relevanten Grid für den InplaceEdit hole, habe ich das Problem, daß ich mit dem SetText keine vernünftige Darstellung hinbekomme. Der Text wird in den Zellen überschrieben, neu markiert, und der Editor springt wieder an und holt aus dem einen Grid den dort stehenden Wert. Wenn man im anderen Grid aber die Eingabe gemacht hat, dann geht diese verloren. Zudem habe ich noch einige Steuerungen bezüglich der Position des Mauszeigers, wodurch es sein kann, daß goEditing nicht mehr in Options enthalten ist. Siehe auch mein 2. Posting...

Jan
  Mit Zitat antworten Zitat
Benutzerbild von ibp
ibp

Registriert seit: 31. Mär 2004
Ort: Frankfurt am Main
1.511 Beiträge
 
Delphi 7 Architect
 
#4

AW: tStringGrid und In-Place-Editor Problem

  Alt 7. Aug 2010, 19:52
hast du schon mal bei den Schweizern nachgesehen?

Bespiele für Inplace und StringGrid...

einen TMemo mit einer StringGrid-Zelle kombinieren
...eine Combobox als InPlace Editor in einem StringGrid verwenden?
  Mit Zitat antworten Zitat
Schorschi5566

Registriert seit: 6. Feb 2006
197 Beiträge
 
Delphi 10.2 Tokyo Enterprise
 
#5

AW: tStringGrid und In-Place-Editor Problem

  Alt 9. Aug 2010, 00:26
Hallo Jan,

ich würde mir eine eigene StringGridklasse von TStringGrid ableiten und erstmal die Funktionalität für die genaue und gerundete Darstellung einbauen.

Dann brauchst Du schonmal das zweite StringGrid nicht mehr.


Grüße,
Uwe
Uwe
"Real programmers can write assembly code in any language." - Larry Wall
Delphi programming rocks
  Mit Zitat antworten Zitat
BoolString

Registriert seit: 2. Feb 2009
Ort: Varel
70 Beiträge
 
RAD-Studio 2009 Pro
 
#6

AW: tStringGrid und In-Place-Editor Problem

  Alt 18. Aug 2010, 14:16
Herzlichen Dank für eure Antworten. Da mein Urlaub vorbei ist, ist die Zeit für private Projekte mal wieder sehr begrenzt. Aus dem Grund die sporadischen Rückmeldungen...

Ein OnExit für einen In-place-Editor habe ich nicht wirklich funktionierend gelöst bekommen. Aus dem Grund ist der Ansatz jetzt geändert. Die Werte im Editor-Formular werden auch weiterhin nur im Grid gehalten. Nach außen hin stelle ich im OnDraw die entsprechend aufbereiteten Werte dar. Da sicherlich auch andere schon mal auf der Suche nach so etwas waren hier ein kleines Code-Beispiel:

Delphi-Quellcode:
unit uMain;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Grids, ComCtrls, StdCtrls;

type
  TForm1 = class (TForm)
    edValuePrecision: TEdit;
    UpDown1: TUpDown;
    StringGrid1: TStringGrid;
    procedure UpDown1ChangingEx(Sender: TObject; var AllowChange: Boolean; NewValue: SmallInt; Direction: TUpDownDirection);
    procedure FormCreate(Sender: TObject);
    procedure StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer; Rect: TRect; State: TGridDrawState);
  private
    { Private-Deklarationen }
    fFormatValueString : String;
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}




procedure TForm1.FormCreate(Sender: TObject);
begin
  StringGrid1.Options := StringGrid1.Options + [goEditing];

  UpDown1.Min := 0;
  UpDown1.Max := 16;
  UpDown1.Position := 2;
end;



Procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer; Rect: TRect; State: TGridDrawState);

Var aCellString : String;
    aCellValue : Double;
begin

 aCellString := StringGrid1.Cells [aCol, aRow];

//do we display a data cell?
 If (aRow >= StringGrid1.FixedRows) and (aCol >= StringGrid1.FixedCols) THen
 Begin

   //adjust background colour when cell is selected
   If gdSelected In State THen
   Begin
     StringGrid1.Canvas.Brush.Color := clSkyBlue;
     StringGrid1.Canvas.FillRect (Rect);
   end
   Else
   Begin
     StringGrid1.Canvas.Brush.Color := clWhite;
     StringGrid1.Canvas.FillRect (Rect);
   end;

   // does the cell contain a value?
   If TryStrToFloat (aCellString, aCellValue) THen
   Begin
     // if so, display formatted value
     StringGrid1.Canvas.Font.Color := clBlack;
     aCellString := Format (form1.fFormatValueString, [aCellValue]);

     DrawText (StringGrid1.Canvas.Handle,
               PChar (aCellString),
               Length (aCellString),
               Rect,
               DT_SINGLELINE or DT_RIGHT );
   end
   Else
   Begin
     // otherwise display the raw string in a different colour
     StringGrid1.Canvas.Font.Color := clRed;
     DrawText (StringGrid1.Canvas.Handle,
               PChar (aCellString),
               Length (aCellString),
               Rect,
               DT_SINGLELINE or DT_LEFT );
   end;
   Exit;
 end;


  // upper left corner for matrix title
  If (aRow = 0) And (aCol = 0) THen
  Begin
    StringGrid1.Canvas.Brush.Color := clMenu;
    StringGrid1.Canvas.FillRect (Rect);

    //reduce the grid rectangle to keep the borders
    Inc (Rect.Left, 2);
    Dec (Rect.Right, 2);

    // display the title of the matrix in the upper left corner
    StringGrid1.Canvas.Font.Color := clRed;
    DrawText (StringGrid1.Canvas.Handle,
              PChar (aCellString),
              Length (aCellString),
              Rect,
              DT_SINGLELINE or DT_LEFT );
    Exit;
  end;

  // do we perform actions in the cells for the column-/row-captions?
  If (aRow = StringGrid1.FixedRows-1) And (aCol > StringGrid1.FixedCols-1) Or
     (aRow > StringGrid1.FixedRows-1) And (aCol = StringGrid1.FixedCols-1) THen
  Begin
    StringGrid1.Canvas.Brush.Color := cl3dLight;
    StringGrid1.Canvas.FillRect (Rect);

    //reduce the grid rectangle to keep the borders
    Inc (Rect.Left, 2);
    Dec (Rect.Right, 2);

    StringGrid1.Canvas.Font.Color := clBlue;
    Drawtext (StringGrid1.Canvas.Handle,
              PChar (aCellString),
              Length (aCellString),
              Rect,
              DT_SINGLELINE or DT_LEFT );
  end;
end;



procedure TForm1.UpDown1ChangingEx(Sender: TObject; var AllowChange: Boolean; NewValue: SmallInt; Direction: TUpDownDirection);
begin
  // renew the format string
  If NewValue >= 0 THen fFormatValueString := '%8.'+IntToStr (NewValue)+'f'
                   Else fFormatValueString := '%8.0f';

  // force the stringgrid to update
  StringGrid1.Invalidate;
  StringGrid1.Repaint;
end;

end.
Obiges Beispiel verlangt ein StringGrid, ein Edit-Feld und eine UpDown-Schaltfläche auf dem Formular. Die jeweiligen Events sind zu setzen. Ergebnis ist ein editierbares StringGrid, bei dem Zahlen in jeder Zelle rechtsbündig dargestellt werden und String/fehlerhafte Zahlen linksbündig in rot.

Um auf das ausgangsproblem zurückzukommen:
In diesem Fall erzeugt das die gewünschte Funktionalität auf eine deutlich einfachere Weise als ursprünglich angedacht. Dennoch kann ich mir einige Fälle vorstellen, in denen ein OnExit für einen In-Place-Editor wünschenswert wäre.

@ibp
Die Schweizer ComboBox Version habe ich versucht in meinem Projekt mit umzusetzen. Allerdings wird hier OnSelectCell verwendet. Dies beißt sich leider etwas mit meinem Dateneditor. Wenn der 'In-Place' Editor in Form eines tEdit noch aktiv ist und eine gleichzeitig eine Selection angelegt wird oder der Nutzer Spalten/Zeilen verschiebt, dann bleiben an flascher Stelle leider teilweise die werte stehen...

Ansonsten schönen Dank und falls noch jemand was zu ursprünglichen Problem hat.....

Jan
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 04: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