TComboBox与TListBox项删除异常:访问冲突问题解决
Delphi 删除TListBox与TComboBox项时的访问冲突问题解决
最近碰到一个典型的低级错误,分享出来帮大家避坑:我在实现从TEdit向TListBox和TComboBox同步添加项的功能时一切正常,但在删除ListBox选中项(同时要删掉ComboBox中对应项)的时候触发了访问冲突错误。
原错误代码
procedure TMainForm.Button1Click(Sender: TObject); begin ListBox1.Items.Add(Edit1.Text); ComboBox1.Items.Add(Edit1.Text); end; procedure TMainForm.Button2Click(Sender: TObject); begin ListBox1.Items.Delete(ListBox1.Selected.Index); ComboBox1.Items.Delete(ComboBox1.Items.IndexOf(ListBox1.Selected.Text)); end;
问题原因
这个错误的核心是执行顺序导致的无效对象访问:当你先调用ListBox1.Items.Delete删除选中项后,ListBox1.Selected会立即变成nil(因为选中的项已经不存在了),这时候再试图访问ListBox1.Selected.Text,就相当于去访问一个已经被销毁的对象属性,直接触发访问冲突。
修正后的代码
只需要调整删除操作的顺序,先在ListBox选中项还存在的时候完成ComboBox的删除操作,再去删除ListBox的项:
procedure TMainForm.Button1Click(Sender: TObject); begin ListBox1.Items.Add(Edit1.Text); ComboBox1.Items.Add(Edit1.Text); end; procedure TMainForm.Button2Click(Sender: TObject); begin ComboBox1.Items.Delete(ComboBox1.Items.IndexOf(ListBox1.Selected.Text)); ListBox1.Items.Delete(ListBox1.Selected.Index); end;
更健壮的写法(可选)
为了避免用户在没有选中任何项时点击删除按钮引发错误,还可以加上选中项的判断,同时先把要删除的文本存起来,进一步避免意外:
procedure TMainForm.Button2Click(Sender: TObject); var DeleteText: string; begin // 先判断是否有选中项,防止空指针 if Assigned(ListBox1.Selected) then begin DeleteText := ListBox1.Selected.Text; ListBox1.Items.Delete(ListBox1.Selected.Index); ComboBox1.Items.Delete(ComboBox1.Items.IndexOf(DeleteText)); end; end;
这样调整后,不仅解决了访问冲突的问题,还让程序的容错性更强。
内容的提问来源于stack exchange,提问作者bear
相关产品推荐
相关产品推荐

