Jak wykryć zakończenie edycji Cells w StringGrid

0

Witam,

Muszę dodać zdarzenie do oryginalnego komponentu czy można to zrobić jakoś inaczej?
Może ktoś podesłać kod dodania zdarzenia?

Pozdrawiam

0
SetEditText(Sender: TObject; ACol,  ARow: Integer; const Value: string);

Jak z Value mam wyciągnąć informację że edycja się zakończyła?

0
dasej napisał(a):

Muszę dodać zdarzenie do oryginalnego komponentu czy można to zrobić jakoś inaczej?

Bez pełnych źródeł komponentu nie dodasz takiego zdarzenia. Ehh, patrz niżej. O subclassingu zapomniałem. :D

dasej napisał(a):

Jak z Value mam wyciągnąć informację że edycja się zakończyła?

To zależy co konkretnie chcesz zrobić. Argument Value zawsze posiada nową wartość wprowadzoną przez użytkownika, dzięki czemu możesz ją na bieżąco modyfikować, jeśli wprowadzono niepoprawne dane.

3

Może i wydaje się trochę przekombinowane ale działa:

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.Grids, Vcl.StdCtrls;

type
  TOnSetEditMode = procedure(Sender: TObject; Row, Col: Integer; EditMode: Boolean) of object;

  TStringGrid  = class(Vcl.Grids.TStringGrid)
  private
    fEditMode: Boolean;
    fLastRow, fLastCol: Integer;
    fOnSetEditMode: TOnSetEditMode;
    procedure DoSetEditMode;
  protected
    procedure WMSetFocus(var Msg: TWMSetFocus); message WM_SETFOCUS;
    procedure WMKillFocus(var Msg: TWMKillFocus); message WM_KILLFOCUS;
    procedure WMLButtonDblClk(var Msg: TWMLButtonDblClk); message WM_LBUTTONDBLCLK;
    procedure WMLButtonDown(var Msg: TWMLButtonDown); message WM_LBUTTONDOWN;
    procedure WMKeyDown(var Msg: TWMKeyDown); message WM_KEYDOWN;
  public
     property OnSetEditMode: TOnSetEditMode read fOnSetEditMode write fOnSetEditMode;
  end;



  TForm1 = class(TForm)
    StringGrid1: TStringGrid;
    Memo1: TMemo;
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
    procedure OnSetEditMode(Sender: TObject; Row, Col: Integer; EditMode: Boolean);
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TStringGrid.DoSetEditMode;
begin
  if (fEditMode <> Self.EditorMode) and (Assigned(fOnSetEditMode)) then
    fOnSetEditMode(Self, fLastRow, fLastCol, Self.EditorMode);
  fEditMode:= Self.EditorMode;
end;

procedure TStringGrid.WMLButtonDown(var Msg: TWMLButtonDown);
begin
   inherited;
   DoSetEditMode;
end;

procedure TStringGrid.WMLButtonDblClk(var Msg: TWMLButtonDblClk);
begin
   inherited;
   DoSetEditMode;
end;


procedure TStringGrid.WMSetFocus(var Msg: TWMSetFocus);
begin
   inherited;
   fLastRow:= Self.Row;
   fLastCol:= Self.Col;
   DoSetEditMode;
end;



procedure TStringGrid.WMKillFocus(var Msg: TWMKillFocus);
begin
   inherited;
   fLastRow:= Self.Row;
   fLastCol:= Self.Col;
   DoSetEditMode;
end;

procedure TStringGrid.WMKeyDown(var Msg: TWMKeyDown);
begin
   inherited;
   DoSetEditMode;
end;


procedure TForm1.FormCreate(Sender: TObject);
begin
  Memo1.Lines.Clear;
  StringGrid1.OnSetEditMode:= OnSetEditMode;
end;

procedure TForm1.OnSetEditMode(Sender: TObject; Row, Col: Integer; EditMode: Boolean);
const
  EDIT_MODES: array [Boolean] of string = ('Po Edycji ', 'Edycja ');
begin
  Memo1.Lines.Add(EDIT_MODES[EditMode] + Format('%0:d X %1:d', [Row, Col]));
end;

end.
0

Dzięki** kAzek.**
abrakadaber jak obsłużyć to zdarzenie?

0

Dobrze by było wiedzieć, co konkretnie chcesz zrobić. Bo na pytanie „jak obsłużyć to zdarzenie” można jedynie odpowiedzieć „normalnie, wygenerować je i napisać w nim swój kod”. Co konkretnie potrzebujesz zrobić? Filtrować dane podczas wprowadzania i/lub po jego zakończeniu, czy tylko przechwycić moment zakończenia wprowadzania?

0

Witam furious programming,
Odpowiedź na Twoje pytanie jest zawarta w temacie.
"Jak wykryć zakończenie edycji Cells w StringGrid"

Chcę wiedzieć kiedy użytkownik zakończył edycje w Cells.

0

ale po co chcesz to wiedzieć albo inaczej - co chcesz z tą wiedzą zrobić? Od odpowiedzi na to pytanie zależy czy OnSetEditText wystarczy czy nie a jak wystarczy to jak to obsłużyć.

0

@furious programming: Odpowiedź nie jest taka banalna bo "skończył edycję" to takie trochę niejasne określenie i chyba trzeba to rozbić na części pierwsze.
Najbliższa prawdy jest chyba podpowiedź od @kAzek ale faktycznie dość zagmatwana. Nigdy się nad tym nie zastanawiałem a nawet jeśli kiedyś to już nie pamiętam jednak bym poszedł drogą obsłużenia:

  • onKeyUp
  • onDeactivate
  • on[Jakieć schowki wklejane myszką]
  • onClick ( wykrywanie czy zmieniła się bieżąca komórka ).
  • i pewnie jeszcze coś.

Jednak wracają do pytania. Kiedy jest koniec edycji?
Zakładam, że autor wraz z końcem edycji chciałby to co wpisano zapisać np. do bazy lub pliku... W takim przypadku możliwości jest sporo bo czy kliknięcie w czasie pisania w innej komórce jest oczekiwanym zakończeniem edycji czy nieumyślnym błędem, czy wyjście z komórki przez zamknięcie całego formularza jest oczekiwanym zakończeniem edycji itd...

0

No nie jest proste, dlatego rozwiązanie podane przez @kAzek jest dobrym pomysłem. Problem polega na tym, że nie wiemy co konkretnie pytacz chce zrobić, dlatego nie wiadomo czy OnSetEditText może tu być zastosowane czy trzeba samemu (komunikatami) dopierać się do tego. No i jak, domyślać się mamy? Podawać wszystkie możliwe rozwiązania zgadując intencje autora?

Po raz kolejny OP nie dostarcza ważnych informacji, więc po raz kolejny nie ma jak mu pomóc, a nie wiedzieć czemu zamiast doprecyzować i podać konkretne informacje na temat konkretnej potrzeby, ten woli napisać tyle:

dasej napisał(a):

Odpowiedź na Twoje pytanie jest zawarta w temacie.

Skoro tak, to spoko. Kod realizujący „odpowiedź na pytanie w temacie” podał @kAzek, więc problem został rozwiązany. A nie, czekaj — jego kod też został olany, nieważne czy realizuje założenia czy nie. Dziwny wątek.

0

Mój kod autor powinien sobie dostosować np. jak wiadomo inherited to w tym przypadku domyślna obsługa komunikatu gdyby ją wstawić dopiero po obsłudze zdarzenia i wywołać lub nie w zależności od tego czy są spełnione jakieś warunki można by pozwalać zakończyć edycję lub nie... ale czy naprawdę trzeba podać wszystko na tacy tym bardziej, że nie wiadomo co tak naprawdę autor wątku chce osiągnąć.

0

Chcę wiedzieć czy zakończyła się edycja Cells,
nie interesuje mnie naciśnięcie klawisza Enter tylko zakończenie edycji.
gdyż może ten kod wystąpić też przy CTRL+Enter.

@kAzek, adaptuję Twój kod do mich potrzeb, Dzięki.

0

Temat stary.
Dawno rozwiązany w poniższy sposób.

procedure TForm1.StringGrid1SetEditText(Sender: TObject; ACol,
                           ARow: Integer; const Value: string);
var endEdit : string; // zmienna tylko do prezentacji
begin
      endEdit :='nie';
      if (CompareText(FPrevValue, Value) = 0) then
         begin
            endEdit :='tak';
            // tu wstawić kod który ma coś robić po zakończeniu edycji
         end;
      // zmienna z sekcji   private
      FPrevValue := Value;
end;

1 użytkowników online, w tym zalogowanych: 0, gości: 1