2

TZQueryTDBCheckBoxes が割り当てられた複数のブール フィールドを持つDataSet ( ) があります。

これらのチェックボックスには " OnClick" イベントが割り当てられており、フィールド値 (チェックボックスに割り当てられている) を変更するたびにトリガーされます。

問題は、データセットで行う多くの操作中に、これらのイベントをトリガーする必要がないことです。

を呼び出してみましDataSet.DisableControlsたが、 を呼び出した直後にイベントが呼び出されますDataSet.EnableControls

だから私の質問は - データベース対応コントロールイベントのトリガーを無効にする方法はありますか?

編集(全体像):

たとえばデータの保存中に例外が発生した場合、デフォルト値 (または保存前の値) をロードする必要があります。そのデータをロードしている間、これらすべてのイベント (TDBCheckBoxes およびその他のデータ対応コントロール) がトリガーされ、ラグやデータの不要な変更さえも作成するあらゆる種類の操作を実行します。それらすべてを無効にする普遍的なソリューションを探しています。短期間。

4

3 に答える 3

6

Guillem の投稿に基づく構築:

すべてをオフにします。

以下に示すように、for ループを使用してフォームの各コンポーネントを走査し、プロパティを目的の値に変更します。

後で元のプロパティ値に戻したい場合は、元の値を保存する必要があります (以下では OldEvent が使用されているため)。

編集:以下のコードは、議論されている重要な概念を示しています。コンポーネントが実行時に追加または削除される場合、またはメモリの使用量を最小限に抑えたい場合は、動的配列を使用し、Pieter が示唆するように、コンポーネントにインデックスを付けるのではなく、コンポーネントへのポインタを格納します。

  const
    MAX_COMPONENTS_ON_PAGE = 100; // arbitrarily larger than what you'd expect. (Use a dynamic array if this worries you.
  var 
     OldEvent: Array[0.. MAX_COMPONENTS_ON_PAGE - 1] of TNotifyEvent; // save original values here
     i: Integer;
  begin                                 
   for i := 0 to ComponentCount - 1 do 
   begin
     if (Components[i] is TCheckBox)  then 
        begin
          OldEvent[i] := TCheckBox(Components[i]).OnClick; // remember old state  
          TCheckBox(Components[i]).OnClick := nil;
        end
      else if (Components[i] is TEdit) then
         begin
           OldEvent[i] := TEdit(Components[i]).OnClick; // remember old state  
           TEdit(Components[i]).OnClick := nil;          
         end;
    end;

以前の値に戻す

 for i := 0 to ComponentCount - 1 do 
 begin
   if (Components[i] is TCheckBox)  then
      TCheckBox(Components[i]).OnClick := OldEvent[i]
   else if (Components[i] is TEdit)  then
      TEdit(Components[i]).OnClick := OldEvent[i];
 end;

すべての if ステートメントを、「このコンポーネントには OnClickEvent がありますか」と答える 1 つの一般的なテストにまとめる方法があるかもしれませんが、それが何であるかはわかりません。

誰かが私の答えを建設的に批判してくれることを願っています (反対票を投じるだけではなく)。

于 2012-06-19T12:10:51.527 に答える
5

これを行う1つの方法は次のとおりです。

var
  Event : TNotifyEvent;    
begin
  Event := myCheckbox.OnClick;
  try
    myCheckbox.OnClick := nil;
    //your code here
  finally
    myCheckbox.OnClick := Event;
  end;
end;

HTH

于 2012-06-19T07:57:17.463 に答える
2

の内部設計では、プロパティが変更されるたびTCustomCheckBoxにメソッドがトリガーされます。実際にクリックするか、コードで設定してください。そして、これは、データセット内のリンクされたフィールドの値を表示するようにコントロールが更新されるため、呼び出すときにここで発生します。ClickCheckedEnableControls

TButtonControl(これはTCustomCheckBoxから継承するものです)にはプロパティがありますClicksDisabled。DisableControls / EnableControls呼び出しの代わりに(またはそれに加えて)これを使用します。残念ながら、それは保護されており、公開されてTCustomCheckBoxいませんが、小さなハックを使用してアクセスできます。

type
  TButtonControlAccess = class(TButtonControl)
  public
    property ClicksDisabled;
  end;

...

TButtonControlAccess(MyCheckBox1).ClicksDisabled := True;
// do some dataset stuff
TButtonControlAccess(MyCheckBox1).ClicksDisabled := False;

もちろん、これをすべてのコンポーネントをチェックし、コントロールがTCustomCheckBox他の基準を継承している場合はこのプロパティを設定するメソッドに入れることができます。

于 2012-06-19T18:54:19.930 に答える