3

私のケースの選択基準として Sender を TObject として使用したい ... ステートメント

procedure TForm.ShowGUI (Sender: TObject);
begin
  case sender of
      ToolButton1: begin
          do_something;         
        end;

      ToolButton2: begin
          /// 
        end;

      ToolButton3: begin
          do_stufff_here; 
        end;

      ToolButton3: begin 
          /// 
        end;

      else ;

  end;
end;

case ステートメントで要求されたように、送信者を序数型にするトリックはありますか?

4

2 に答える 2

10

Senderを整数に変換することで簡単に序数に変換できます(例: NativeUInt(Sender)- しかし、caseステートメントは「枝」の定数式を想定しているため、ToolButton1..ToolButton3は定数ではなく、変数であるため、これは役に立ちません。

たとえば、ボタンのプロパティでケースを実行できます。たとえば、それぞれに意味のあるプロパティをToolButton与えます。Tag次に、次のようなことができます。

case (Sender as TToolButton).Tag of
  1: ; // ToolButton1 was pressed
  2: ; // ToolButton2 was pressed        
end;

David が提案したように:使用しているコントロールに、その機能に直接関連するプロパティがない限り (ほとんどありません)、単純な連鎖 if ステートメントの方が読みやすいかもしれません。私のTag最初の提案のようなプロパティは、具体的に構成する必要があり、それはエラーを導入する別の方法です。例: ボタンをコピーして貼り付けたが、タグを変更するのを忘れた可能性があります。同じタグを持つ 2 つのボタンがあります。

まず、コードから使用しているすべてのコンポーネントの名前を変更し、適切な名前を付ける必要があります。次に、次のように書くことができます。

if (Sender = tbAlignTextLeft) then
  begin
     // The tool-button for left text alignment was pressed
  end
else if (Sender = tbAlignTextCenter) then
  begin
    // Center-alignment button was pressed
  end
else
  begin
    // This would be the default action. If it were me, I'd raise an exception here.
  end
于 2013-02-14T08:03:56.090 に答える
6

列挙型をコントロールに関連付けるために、ランタイム サポートを少し追加することを検討してください。

最初に列挙型を作成します。

type
  TControlID = (cidAlignTextLeft, cidAlignTextRight, ....);

次に、辞書をフォームに追加します。

FControlIDs: TDictionary<TControl, TControlID>;

次に、フォームのコンストラクターで辞書を作成して入力します。

FControlIDs := TDictionary<TControl, TControlID>.Create;
FControlIDs.Add(tbAlignTextLeft, cidAlignTextLeft);
FControlIDs.Add(tbAlignTextRight, cidAlignTextRight);
....

コードのこのセクションは、フォームのコンストラクターでインライン化するのではなく、別のローカル ヘルパー関数に配置する必要があります。

これで、ケースステートメントを書くことができます:

case FControlIDs[Sender as TControl] of
cidAlignTextLeft:
  ....
cidAlignTextRight:
  ....
于 2013-02-14T08:54:50.777 に答える