MaskEdit für DBGrid

Für Themen zu Datenbanken und Zugriff auf diese. Auch für Datenbankkomponenten.
Antworten
Michl
Beiträge: 2511
Registriert: Di 19. Jun 2012, 12:54

MaskEdit für DBGrid

Beitrag von Michl »

Hallo allerseits,

ich hatte für mich einen kleinen Terminplaner gebaut (PostgreSQL mit ZEOS). Relativ schnell wars zusammengeklickt. Da ich eine "in der Tabelle"-Bearbeitung sehr schön fand, habe ich das auch so umgesetzt. In anderen Projekten habe ich immer die Grid nur zur Ansicht, die Bearbeitung erfolgt dann durch externe Eingabefelder.

Nun habe ich auch Felder mit Datum-Werten. Eine Eingabe von fehlerhaften Werten führte zu Exceptions. Nach Suche im Netz nach der Möglichkeit von der Nutzung eines MaskEdits für die Spalte, musste ich feststellen, dass dieses Feature noch nicht implementiert ist, zumindest habe ich es nicht aktiviert bekommen.

Also dachte ich mir, ersetze ich einfach das normale Edit durch ein TDateEdit, was mir letztendlich auch geglückt ist, konnte jetzt erstmal kein weiteres Fehlverhalten auslösen. Ich finde diese Verbiegungen allerdings ganz schön wild und nicht unbedingt sauber. Mein Code:

Code: Alles auswählen

const
  DateChanged: Boolean = False;                           //wurde eine Änderung an der Datums-Zelle vorgenommen?!
  NotExit: Boolean = False;                               //Verhindern, dass Grid den Focus verliert
 
var
  TermineForm: TTermineForm;                              //Meine Form
  AktField: Integer;                                      //Query.Field[ AktField ], das editiert wird
 
implementation
 
{$R *.lfm}
 
procedure TTermineForm.DateEditKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  Case Key of
    13, 38, 40: Key:=9;                                   //Enter, Pfeil hoch/runter wie Tab behandeln
  end;
  if Key = 9 then NotExit:=True;                          //Kein Focusverlust der Grid!!!
end;
 
procedure TTermineForm.DataSourceDataChange(Sender: TObject; Field: TField);
begin
  if DateChanged then DateUpdate;                         //macht das Update des aktuellen Records
end;
 
procedure TTermineForm.DateEditAcceptDate(Sender: TObject;
  var ADate: TDateTime; var AcceptDate: Boolean);
begin
  DateEdit.Date:=ADate;
  if DateChanged then DateUpdate;                         //macht das Update des aktuellen Records
end;
 
procedure TTermineForm.DateEditCustomDate(Sender: TObject; var ADate: string);
var
  Dummy:TDateTime;
begin
  if not TryStrToDate(ADate, Dummy) then ADate:='01.01.1900';
end;
 
procedure TTermineForm.DateEditEnter(Sender: TObject);
begin
  DateChanged:=True;
end;
 
procedure TTermineForm.GridExit(Sender: TObject);
begin
  if NotExit then begin                                   //Verhindern, dass das Grid den Focus verliert, bei Ende Bearbeitung Datum
    Query.Refresh;
    Grid.SetFocus;
    NotExit:=False;
  end;
end;
 
procedure TTermineForm.GridSelectEditor(Sender: TObject; Column: TColumn;
  var Editor: TWinControl);
begin
  case Query.Fields[Column.Index].DataType of
    ftDate:begin
             Query.Edit;                                  //Query für update bereit machen
 
             DateEdit.Parent:=Grid;                       //DateEdit in Celle der Grid zeichnen
             AktField:=Column.Index;
             DateEdit.BoundsRect:=Grid.SelectedFieldRect;
             DateEdit.Text:=Query.Fields[AktField].AsString;
 
             Editor:=DateEdit;
           end;
//    ftTime:status.Write(Inttostr(Column.Index)+': Zeit');
//    else status.Write(Inttostr(Column.Index)+': String oder Unbekannt');
  end;
end;
 
procedure TTermineForm.DateUpdate;                        //macht das Update des aktuellen Records
var
  NewDate:TDateTime;
begin
 
  DateChanged := False;                                   //Rücksetzen der "Change"-Markierung
 
  NewDate:=DateEdit.Date;
  if NewDate > 3 then begin                               //Nur zuweisen, wenn Date i.O. (01.01.1900 - mein InitDatum)
//    Status.Write('[DateUpdate] Änder zu Datum: '+DateToStr(NewDate));
    Query.Fields[AktField].AsDateTime:=NewDate;
  end else
    Query.Fields[AktField].AsString:='';                  //Üngültiges Datum -> update mit ''
 
  Query.UpdateRecord;
  Query.Refresh;
 
end;   
Auf der Form muss noch eine weitere fokusierbare Komponente sein, sonst bekomme ich den Focus vom DateEdit bei "Enter" nicht weg.
Kann man den Editor mit dem TDateEdit anders/besser ersetzen, dass dessen Rückgabewert direkt in das Query geschrieben wird???
Oder gibt es eine einfachere Lösung für die Nutzung eines MaskEdits, ich steh da irgendwie auf dem Schlauch... :?: :?: :?:

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

Antworten