5

Delphiでは、これを行う必要がある場合があります...

function TForm1.EDIT_Click(Sender: TObject);
begin
  (Sender As TEdit).Text := '';
end;

...しかし、場合によっては、次のような他のオブジェクト クラスで関数を繰り返す必要があります...

function TForm1.COMBOBOX_Click(Sender: TObject);
begin
  (Sender As TComboBox).Text := '';
end;

...オペレーターAsが柔軟性を受け入れないためです。.Textの後に来るを許可するには、クラスを認識している必要があり()ます。

場合によっては、指定できない類似のビジュアル コントロールを使用して同じことを行う必要があるため、コードが類似の要素でいっぱいになるfunctionsことがあります。procedures

あくまでも使用例です。通常、これらのコードをより複雑なコードで使用して、多くのコントロールやその他の種類のオブジェクトで標準的な目的を達成します。

これらのタスクをより柔軟にするための代替手段またはトリックはありますか?

4

7 に答える 7

12

RTTI を使用して、無関係なクラスの同様の名前のプロパティに対して一般的なタスクを実行します。たとえば、次のようになります。

Uses
 ..., TypInfo;

// Assigned to both TEdit and TComboBox
function TForm1.ControlClick(Sender: TObject);
var
  PropInfo: PPropInfo;
begin
  PropInfo := GetPropInfo(Sender, 'Text', []);
  if Assigned(PropInfo) then
    SetStrProp(Sender, PropInfo, '');
end;

場合によっては、一部のコントロールは使用Textし、一部はCaption代わりに使用します。

function TForm1.ControlClick(Sender: TObject);
var
  PropInfo: PPropInfo;
begin
  PropInfo := GetPropInfo(Sender, 'Text', []);
  if not Assigned(PropInfo) then
    PropInfo := GetPropInfo(Sender, 'Caption', []);
  if Assigned(PropInfo) then
    SetStrProp(Sender, PropInfo, '');
end;
于 2012-07-05T04:16:45.597 に答える
10

演算子を使用できます。isこのサンプルを試してください

 if Sender is TEdit then
  TEdit(Sender).Text:=''
 else
 if Sender is TComboBox then
  TComboBox(Sender).Text:='';
于 2012-07-04T22:02:39.253 に答える
5

absoluteキーワードを使用すると、面倒な型キャストをなくすことができます。これにより、同じメモリ位置 (この場合はイベント パラメーターと同じ位置) を占有する異なる型の変数を宣言できます。

「is」を使用して型チェックを実行する必要がありますが、他の点では、このアプローチは少しクリーンですが安全です。

procedure TMyForm.ControlClick(Sender: TObject);
var
  edit: TEdit absolute Sender;
  combo: TComboBox absolute Sender;
   :
begin
  if Sender is TEdit then
    edit.Text := ''
  else if Sender is TComboBox then
    combobox.Text := ''
  else
   :
end;

この言語機能の使用については、ほぼ 3 年前にブログで詳しく説明しました。

于 2012-07-05T03:48:24.530 に答える
2

これについて言及している回答がここにないため、コメントを回答として投稿しています。SetTextBuf は TControl のパブリック メソッドです。このメソッドは、SetText ウィンドウ メッセージを介して内部テキスト データ メンバーを設定するために使用されます。これは、TControl の子孫が Caption プロパティと Text プロパティの両方を更新する方法です。したがって、TButton、TEdit、TComboBox などのすべての TControl の子孫は、次のタイプのコードを使用して機能します。また、RTTI を使用する必要はありません。

function TForm1.EDIT_Click(Sender: TObject);
begin
  (Sender as TControl).SetTextBuf('Text or Caption'); // will work for both the Caption and text property
end;
于 2012-07-05T18:22:21.603 に答える
1

tag プロパティを何かに使用しているかどうかはわかりませんが、このような状況では役立ちます。すべての Tedit のタグを 1 に設定し、すべての Tcombobox のタグを 2 などに設定すると、次のことが可能になります。

if Sender is TControl then
  Case TControl(Sender).tag of
    1: TEdit(sender).text := '';
    2: Tcombobox(sender).text := '';
    3....etc
  end;

ちょっと考えただけで、見た目がすっきりして読みやすく/デバッグしやすくなります:)

于 2012-07-05T10:52:28.657 に答える
0

特に@RemyLebeauの人々のおかげで、あらゆる種類のWin ControlまたはData Base Controlに適用されるこのユニバーサル関数を作成できました。必須であるが空の場合、データベースに繰り返し情報がある場合、またはチェックしたいその他の条件がある場合は、コントロールを赤 (または任意の色) にします。true または false の代わりに数値を返すため、多くのチェックの最後にメッセージを 1 つだけ送信して、ユーザーが何回エラーを起こしたかを伝えることができます。

function CheckInput(Control: TWinControl; Condition: Boolean; EmptyState: Integer; Msg: String): Integer;
var
  PropInfo: PPropInfo;
begin
{ os controles que precisam passar por condições para que seu conteúdo seja aceito }
  Result := 0;
  if EmptyState = ciNotEmpty then
  begin
    PropInfo := GetPropInfo(Control, 'Text', []);
    if Assigned(PropInfo) then
    begin
      if GetStrProp(Control, PropInfo) = '' then
      begin
        Condition := False;
        Msg := ciEmptyMsg;
      end;
    end;
  end;
  if not Condition then
  begin
    Result := 1;
    PropInfo := GetPropInfo(Control, 'Color', []);
    if Assigned(PropInfo) then SetPropValue(Control, PropInfo, ciErrorColor);
    if Msg <> '' then ShowMessage(Msg);
  end
  else
  begin
    PropInfo := GetPropInfo(Control, 'Color', []);
    if Assigned(PropInfo) then SetPropValue(Control, PropInfo, ciNormalColor);
  end;
end;
于 2012-07-28T02:57:54.410 に答える
-1

ずっと下に行くと、TEdit と TCombobox の両方が TControl から派生していることに気付くでしょう。テキストの設定に使用するメソッドを見ると、それが TControl によって実装されているメソッドであることがわかります。そのため、次のような醜いことができます。

if (sender is TEdit) or (sender is TComboBox) then
  TEdit(sender).Text:='test';

ここに配置するすべてのオブジェクトが内部で同じメソッドを使用していることを確認する必要があります。そうしないと、アプリケーションが不思議な方法で壊れてしまいます。

于 2012-07-05T06:44:56.157 に答える