我不确定我是否正确行事。我在列表框中有一个对象列表,需要使用IndexOf来获取列表中的对象索引。
if AlarmListBox.items.indexOf(alrm.Tagname) = -1 then
alrm是TAlarm类的对象。
基于StackOverflow C#问题(How Can I Get the Index of An Item in a ListBox?),我尝试覆盖GetHashCode和Equals方法,但它仍然无法正常工作。
Overriden方法:
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,并且永远不会调用或触发这些重写的方法。
我是否正确实施了这些覆盖?如果没有,我应该如何覆盖它们?
示例代码或提示或线索将不胜感激。谢谢,
更新:对于David Heffernan和其他评论或回答的人,我认为问题可能是我传递了两个不同的对象,正如Rob的最后评论所述。我使用TAlarmGroup填充Listbox(UI),但是将TAlarm传入IndexOf,尽管它们都是相同的类。这可能是我的问题。我真正想要做的是使用TAlarmGroup对象填充Listbox,并通过传入字符串(标记名)来搜索listbox.indexof我搜索对象位置。这就是它在Delphi XE上的表现,它运行得很好。上面的代码不是实际的代码。一旦我清除了代码中的混淆,它就可以在不覆盖GetHashcode和Equals方法的情况下工作。
更新:我想,我在这里偶然发现了什么。在Delphi XE或更低版本中,ListBox(UI)提供了一个名为AddObject的方法。它的参数分别是一个字符串和一个对象。因此,当我将对象填充到列表框中时,我还提供了与其一起使用的字符串。当我搜索时,我传入一个字符串或警报组名称。 IndexOf在此字符串上搜索它对我提供的每个对象的字符串,而不是对象的字段(TagName)。在Delphi Prism中,listbox没有与AddObject方法类似的方法,只有Add只接受object作为参数。
答案 0 :(得分:2)
以下是使用您提供的基础TAlarm
课程执行所需操作的示例。我还提供了似乎有效的重载Equals
和GetHashCode
的实现。 (同样,我不是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
中所选项目的外观如下: