列表索引超出TPageControl的范围

Bja*_*olt 7 delphi tpagecontrol delphi-xe

我遇到了一个表现出一些奇怪行为的TPageControl.

控件有3页,但是当我这样做

for I:=0 to PageControl.PageCount-1 do begin
  PageControl.Pages[I].TabVisible := False;
  PageControl.Pages[I].Visible    := Ord(iColorScale.GenerationMode) = I;
end;
Run Code Online (Sandbox Code Playgroud)

执行循环的第一次迭代的第一行时,我得到一个'List index out of bounds(3)'错误

PageControl.Pages[0].TabVisible := False;
Run Code Online (Sandbox Code Playgroud)

现在,当我在调试器中查看PageControl属性时,一切似乎都是有序的.PageCount预计为3,我可以在评估器中看到所有页面及其属性,包括第0页的TabVisible

我在Windows 7机器上使用Delphi XE ..有谁知道发生了什么?我不知所措.

kob*_*bik 7

tldr:设置PageControl.HandleNeeded前设置TabVisible.

这里有一个很好的解释(由Greg Chapman提供):TabSheet上的TabVisible和索引错误
对于将来的SO引用(复制/粘贴):

如果PageControl的句柄被销毁(如果在PageControl或其任何父窗口中设置某些属性导致调用时可能会发生这种情况RecreateWnd),则PageControl会将可见选项卡保存在TStringList(FSaveTabs)中.设置会TabVisible导致调用此例程:

procedure TTabSheet.SetTabShowing(Value: Boolean);
var
  Index: Integer;
begin
  if FTabShowing <> Value then
    if Value then
    begin
      FTabShowing := True;
      FPageControl.InsertTab(Self);
    end else
    begin
      Index := TabIndex;
      FTabShowing := False;
      FPageControl.DeleteTab(Self, Index);
    end;
end; 
Run Code Online (Sandbox Code Playgroud)

在调用期间FPageControl.DeleteTab,PageControl将在必要时重新创建其句柄.在这样做时,它会尝试使用重置可见选项卡FSaveTabs.但是,它可能会混淆,因为它添加的其中一个选项卡FSaveTabs现在是不可见的(TabSheet.FTabShowing = false).这会导致IndexError.所以修复是确保在设置之前重新创建句柄TabVisible.