TPageControl 中的列表索引越界

List index out of bounds in TPageControl

我被一个表现出一些奇怪行为的 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;

我在执行相当于

的循环第一次迭代的第一行时遇到 'List index out of bounds (3)' 错误
PageControl.Pages[0].TabVisible := False;

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

我在 windows 7 机器上使用 Delphi XE。有人知道发生了什么事吗?我很茫然。

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

这里有一个很好的解释(作者 Greg Chapman):TabVisible on TabSheet and index error
供将来参考 (copy/paste):

如果 PageControl 的句柄被破坏(可以 如果在 PageControl 或其任何父 windows 中设置一些 属性 导致调用 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; 

在调用 FPageControl.DeleteTab 期间,PageControl 将在必要时重新创建其句柄。这样做时,它会尝试使用 FSaveTabs 重置可见选项卡。但是,它可能会感到困惑,因为它添加到 FSaveTabs 的选项卡之一现在不可见 (TabSheet.FTabShowing = false)。这会导致 IndexError。因此解决方法是确保在设置 TabVisible 之前重新创建句柄。