Arrays 组合框上的访问冲突清除
我正在使用DelphiXe8编写一个可以访问多个数据库的客户机/服务器应用程序 作为设置表单的一部分,TCOMBOXEX用于显示动态记录数组并从中进行选择,动态记录数组保存每个数据库的信息,两个按钮用于从数组中添加或删除记录 数组保存并加载到单个格式化字符串中,每个记录的name属性用作每个组合框项的标题 在form show和add或remove database(添加或删除数据库)按钮上,会调用一个更新过程,该过程首先清除并重新加载数组,然后重新填充组合框Arrays 组合框上的访问冲突清除,arrays,delphi,combobox,delphi-xe8,Arrays,Delphi,Combobox,Delphi Xe8,我正在使用DelphiXe8编写一个可以访问多个数据库的客户机/服务器应用程序 作为设置表单的一部分,TCOMBOXEX用于显示动态记录数组并从中进行选择,动态记录数组保存每个数据库的信息,两个按钮用于从数组中添加或删除记录 数组保存并加载到单个格式化字符串中,每个记录的name属性用作每个组合框项的标题 在form show和add或remove database(添加或删除数据库)按钮上,会调用一个更新过程,该过程首先清除并重新加载数组,然后重新填充组合框 procedure TSettin
procedure TSettingsForm.UpdateDatabaseCombo;
var
i: integer;
begin
LoadDatabaseList; // Clears and reloads databaselist dynamic array.
with dbCombo.Items do
begin
BeginUpdate;
if Length(DatabaseList) <> 0 then
begin
Clear; // This section works fine.
for i := 0 to High(DatabaseList) do
begin
Add(DatabaseList[i].dbName);
dbCombo.ItemsEx[i].ImageIndex := 17;
end;
end;
if (Length(DatabaseList) < 1) and (Count <> 0) then
begin
Clear; // Access violation on this line.
end;
EndUpdate;
end;
end;
这将再次从组合框中清除最后一项,没有例外,但文本仍然保留
请任何人帮我解决这个问题,也许能指出我所缺少的简单的小东西
添加……。
根据要求,以下是UpdateDatabaseCombo
例程的更新代码
procedure TSettingsForm.UpdateDatabaseCombo;
var
i: integer;
begin
LoadDatabaseList; // Clears and reloads databaselist dynamic array.
if dbCombo.Items.Count <> 0 then
dbCombo.Items.Clear;
with dbCombo.Items do
begin
BeginUpdate;
if Length(DatabaseList) <> 0 then
begin
for i := 0 to High(DatabaseList) do
begin
Add(DatabaseList[i].dbName);
dbCombo.ItemsEx[i].ImageIndex := 17;
end;
end;
EndUpdate;
end;
end;
当组合框为空时,如果调用了
clear
,则程序中的任何位置都会发生异常。非常感谢大家的帮助。我终于找到了问题所在
“天啊,我觉得自己好傻”
罪魁祸首是在OnChange
事件处理程序中,我在其中放置了一条指令,以从databases record password属性填充编辑框,当从combobox中选择数据库时,该属性将自动更改
procedure TSettingsForm.UpdateDatabaseCombo;
var
i: integer;
begin
LoadDatabaseList; // Clears and reloads databaselist dynamic array.
with dbCombo.Items do
begin
BeginUpdate;
if Length(DatabaseList) <> 0 then
begin
Clear; // This section works fine.
for i := 0 to High(DatabaseList) do
begin
Add(DatabaseList[i].dbName);
dbCombo.ItemsEx[i].ImageIndex := 17;
end;
end;
if (Length(DatabaseList) < 1) and (Count <> 0) then
begin
Clear; // Access violation on this line.
end;
EndUpdate;
end;
end;
问题是,我没有添加条件语句来检查数据库列表中是否有要从中加载的项,因此在没有引发异常时
两天浪费在一个简单的if
语句上。我已经有几年没有做任何真正的编程了,我真的很怀念那些让人毛骨悚然的时刻
再次感谢 去掉
with
语句,对每个属性使用dbCombo.Items
,然后使用调试器找出错误所在。这是在代码中使用with
时可能发生的另一个坏事情示例。这使得问题很难发现,调试也不可能(至少在您做正确的事情并取消使用with
)之前)。感谢@Ken的回复,但在这种情况下,您是错的,因为问题不在于with
循环,为了证明这一点,我删除了第二条if
语句,替换为if dbCombo.Items.Count 0,然后在加载数组后立即清除dbCombo.Items,但结果仍然是相同的异常错误。ps对于上次的评论表示抱歉,错误地按了enter。@KenWhite没有错:无论如何,您应该避免使用“with”。不管怎样,我怀疑你的问题在于你没有给我们看的东西。调用dbCombo.Items.Clear两次不应导致AV。请将用于从数据库列表中添加和删除记录的代码添加到您的q中。@Ken,请原谅,我并不是说您对
的使用是错误的,我只是说在这种情况下,这不是问题的原因,无论如何,我现在已经更新了问题以提供更多信息。我认为您应该尝试在配置中启用“使用调试dcu”。然后跑。然后使用调用堆栈确定调用combobox clear时异常发生的确切位置。
procedure TSettingsForm.DBRemoveButtonClick(Sender: TObject);
var
ALength: Cardinal;
i: Cardinal;
begin
ALength := Length(DatabaseList);
Assert(ALength > 0);
Assert(dbCombo.ItemIndex < ALength);
for i := dbCombo.ItemIndex + 1 to ALength - 1 do
DatabaseList[i - 1] := DatabaseList[i];
SetLength(DatabaseList, ALength - 1);
SaveDatabaseList;
UpdateDatabaseCombo;
if dbCombo.Items.Count <> 0 then
dbCombo.ItemIndex := 0;
end;