1

これを正しく行っているかどうかはわかりません。リストボックスにオブジェクトのリストがあり、IndexOf を使用してリスト内のオブジェクトのインデックスを取得する必要があります。

if AlarmListBox.items.indexOf(alrm.Tagname) = -1 then

alrm は TAlarm クラスのオブジェクトです。

StackOverflow C# の質問 ( ListBox 内の項目のインデックスを取得するにはどうすればよいですか? ) に基づいて、GetHashCode と Equals メソッドをオーバーライドしようとしましたが、それでも正しく動作しません。

オーバーライドされたメソッド:

TAlarm = class(System.Object)
  TagName:string;
  private
  protected
  public
  method Equals(obj:System.Object):Boolean; override;
  method GetHashCode:Int32; Override;
end;

method TAlarm.Equals(obj: system.Object):Boolean;
begin
    result := TAlarm(obj).Tagname.Equals(self.Tagname);
end;

method TAlarm.GetHashCode:Int32;
begin
    result := self.GetHashCode;
end;

これは、AlarmListBox に入力する方法です。

AlmGrp:= new TAlarmGroup;
AlarmListBox.items.Add(AlmGrp);

コンパイラはエラーなしでコンパイルしますが、プログラムを 1 行ずつデバッグすると常に -1 が返され、これらのオーバーライドされたメソッドが呼び出されたり起動されたりすることはありません。

これらのオーバーライドを正しく実装していますか? そうでない場合、どのようにオーバーライドすればよいですか?

サンプル コードやヒント、手がかりをいただければ幸いです。ありがとう、

更新:コメントまたは回答した​​ David Heffernan と他の人へ、問題は、Rob の最後のコメントが述べているように、2 つの異なるオブジェクトを渡していることだと思います。リストボックス (UI) に TAlarmGroup を入力しますが、TAalarm を IndexOf に渡しますが、どちらも同じクラスです。これはおそらく私の問題です。私が実際にやろうとしているのは、Listbox に TAlarmGroup オブジェクトを設定し、listbox.indexof を介して文字列 (Tagname) を渡してオブジェクトの場所を検索することです。それがDelphi XEで行われる方法で、うまく機能します。上記のコードは実際のコードではありません。コードの混乱を解消すれば、おそらく GetHashcode と Equals メソッドをオーバーライドしなくても機能するでしょう。

更新:ここで何かに遭遇したと思います。Delphi XE 以下では、ListBox (UI) は AddObject と呼ばれるメソッドを提供します。パラメータはそれぞれ文字列とオブジェクトです。そのため、オブジェクトをリストボックスに入力するときに、それに合わせて文字列も提供しました。検索時に、文字列またはアラーム グループ名を渡しました。IndexOf は、オブジェクトのフィールド (TagName) ではなく、提供した各オブジェクトの文字列に対してこの文字列を検索しました。Delphi Prism では、listbox には AddObject メソッドと同様のメソッドはなく、オブジェクトのみをパラメーターとして受け入れる Add のみです。

4

1 に答える 1

2

TAlarm提供した基本クラスを使用して、必要な処理を実行する例を次に示します。オーバーロードされた実装も提供しましたがEqualsGetHashCodeそれは機能しているようです。(繰り返しになりますが、私はPrism / .NET開発者ではありません。ここで手助けしようとしているだけです。)

// In AlarmClass.pas
type
  TAlarm = class(System.Object)
    TagName:string;
  private
  protected
  public
    constructor;
    method Equals(obj:System.Object): Boolean; override;
    method GetHashCode:Int32; Override;
    method ToString(): String; override;
end;

implementation

method TAlarm.GetHashCode: Int32;
begin
  if Self = nil then
    Result := inherited 
  else
    Result := Self.TagName.GetHashCode;
end;

constructor TAlarm;
begin
  inherited;
end;

method TAlarm.Equals(obj: System.Object): Boolean;
begin
  if  (obj = nil) or (GetType() <> obj.GetType()) then
    Exit(False);
  Result := TAlarm(obj).TagName.Equals(Self.TagName);
end;

method TAlarm.ToString(): String;
begin
  Result := Self.TagName;
end;

// In MainForm.pas
method MainForm.button1_Click(sender: System.Object; e: System.EventArgs);
var
  Idx: Integer;
begin
  Idx := ComboBox1.SelectedIndex;
  if Idx <> -1 then
    ListBox1.SelectedIndex := ListBox1.Items.IndexOf(ComboBox1.Items[Idx]);
end;

method MainForm.MainForm_Load(sender: System.Object; e: System.EventArgs);
var
  i, j: Integer;
  Alarm: TAlarm;
  aList: Array[0..4] of Object;
  aFind: Array[0..1] of Object;
begin
  j := 0;
  for i := 0 to 4 do
  begin
    Alarm := new TAlarm;
    Alarm.TagName := String.Format('Alarm{0}', i);
    aList[i] := Alarm;
    // Place items 1 & 3 in another array of searchable items -
    // just for fun. Not suggesting implementing your app this way
    // by any means.
    if (i mod 2) > 0 then
    begin
      aFind[j] := Alarm;
      Inc(j);
    end;
  end;
  ListBox1.Items.AddRange(aList);
  ComboBox1.Items.AddRange(aFind);
end;

ComboBoxをクリックした後、で選択したアイテムを使用した場合の外観は次のButtonとおりです。

ListBoxで見つかったオブジェクトのスクリーンキャプチャ

于 2011-09-15T23:24:36.697 に答える