Jak wyłączyć zdarzenia gdy przeciągam suwak na Gridzie?

0

Mam komponent DBGrid.
Na zdarzeniach AfterScroll or onCalcFields dataseta wykonuje się dużo obliczeń.
Przechodzenie myszką między zaznaczonymi rekordami trwa około pół sekundy.
Ale jeśli przeciągnę suwakiem na sam dół to wtedy te pół sekundy razy ilość rekordów daje długie czekanie.

W innych pętlach które przelatują po datasecie robię

Dataset.OnAfterScroll := nil
Dataset.OnCalcFields := nil

a na po pętli przywracam te zdarzenia. I wszystko działa szybko.
I tu moje pytanie.
Jak wyłączyć te zdarzenia gdy przeciągam suwak.

0
Pele2 napisał(a):

Mam komponent DBGrid.
Na zdarzeniach AfterScroll or onCalcFields dataseta wykonuje się dużo obliczeń.
Przechodzenie myszką między zaznaczonymi rekordami trwa około pół sekundy.
Ale jeśli przeciągnę suwakiem na sam dół to wtedy te pół sekundy razy ilość rekordów daje długie czekanie.

W innych pętlach które przelatują po datasecie robię

Dataset.OnAfterScroll := nil
Dataset.OnCalcFields := nil

Skoro to tyle trwa, to co Ty tam obliczasz?
Używasz zdarzeń AfterScoll i OnCalcFields - obu? Ale po co?
Oba w/w zdarzenia wykonują się często, a OnCalcFields nawet bardzo często.
Opisz możliwie dokładnie co chcesz uzyskać i jak to realizujesz, bo pewnie jest lepszy sposób na to...
Nie zapomnij o:

  • Wersja Delphi
  • Komponenty bazodanowe
  • Jaka baza danych

a na po pętli przywracam te zdarzenia. I wszystko działa szybko.
I tu moje pytanie.
Jak wyłączyć te zdarzenia gdy przeciągam suwak.

0,5s na zmianę rekordu to nie jest szybko.

Jak wyłączyć?
Nadpisać DBGrida, nadpisując metodę obsługi zdarzenia WM_VSCROLL, która odpowiada za interakcję z pionowym paskiem przewijania.

//MMWIN:CLASSCOPY
unit _MM_Copy_Buffer_;

interface

type
  TMyDBGrid = class(TDBGrid)
  private
    type
      TmyGridDataLink = class(TGridDataLink);
  private
    function AcquireFocus: Boolean;
    procedure WMVScroll(var Message: TWMVScroll); message WM_VSCROLL;
  end;


implementation


procedure TMyDBGrid.WMVScroll(var Message: TWMVScroll);
var
  lDataLink     : TmyGridDataLink;
  SI            : TScrollInfo;
  lAfterScroll,
  lBeforeScroll,
  lOnCalcFields : TDataSetNotifyEvent;
begin
  if not AcquireFocus then Exit;

  lDataLink := TmyGridDataLink(DataLink);

  lAfterScroll  := lDataLink.DataSet.AfterScroll;
  lBeforeScroll := lDataLink.DataSet.BeforeScroll;
  lOnCalcFields := lDataLink.DataSet.OnCalcFields;

  lDataLink.DataSet.AfterScroll  := nil;
  lDataLink.DataSet.BeforeScroll := nil;
  lDataLink.DataSet.OnCalcFields := nil;
  try
    if lDataLink.Active then
      with Message, lDataLink.DataSet do
        case ScrollCode of
          SB_LINEUP: lDataLink.MoveBy(-lDataLink.ActiveRecord - 1);
          SB_LINEDOWN: lDataLink.MoveBy(lDataLink.RecordCount - lDataLink.ActiveRecord);
          SB_PAGEUP: lDataLink.MoveBy(-VisibleRowCount);
          SB_PAGEDOWN: lDataLink.MoveBy(VisibleRowCount);
          SB_THUMBPOSITION:
            begin
              if IsSequenced then
              begin
                SI.cbSize := sizeof(SI);
                SI.fMask := SIF_ALL;
                GetScrollInfo(Self.Handle, SB_VERT, SI);
                if SI.nTrackPos <= 1 then First
                else if SI.nTrackPos >= RecordCount then Last
                else RecNo := SI.nTrackPos;
              end
              else
                case Pos of
                  0: First;
                  1: lDataLink.MoveBy(-VisibleRowCount);
                  2: Exit;
                  3: lDataLink.MoveBy(VisibleRowCount);
                  4: Last;
                end;
            end;
          SB_BOTTOM: Last;
          SB_TOP: First;
        end;
  finally
   lDataLink.DataSet.AfterScroll  := lAfterScroll;
   lDataLink.DataSet.BeforeScroll := lBeforeScroll;
   lDataLink.DataSet.OnCalcFields := lOnCalcFields;
  end;
end;

function TMyDBGrid.AcquireFocus: Boolean;
begin
  Result := True;
  if CanFocus and not (csDesigning in ComponentState) then
  begin
    SetFocus;
    Result := Focused or (InplaceEditor <> nil) and InplaceEditor.Focused;
  end;
end;

end.

Oczywiście musisz posługiwać się tak zmodyfikowanym DBGridem - możesz go sobie zarejestrować jako własny komponent... Jeżeli nie wiesz jak, to takie rozwiązania zdecydowanie nie są dla Ciebie.

I na koniec - zdecydowanie nie jest to dobry pomysł na rozwiązanie Twojego problemu, a przynajmniej wg mnie - i to z wielu powodów.
Pewnie inni mają lepsze pomysły, zwłaszcza mistrzowie w temacie "jak powinno się pisać aplikacje bazodanowe w Delphi" ;-)

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