Delphi PageControl隐藏TabSheet后TabIndex匹配异常的解决方案问询
问题原因
Delphi的TPageControl控件的TabIndex属性记录的是当前可见标签的顺序索引,而非设计时Pages数组的固定索引。当你隐藏部分标签后,剩余可见标签的TabIndex会自动重新排序,所以你隐藏Pages[0]后,原本设计时索引为1的标签可见索引就变成了0,这就是你原有逻辑失效、设置ActivePageIndex:=1不生效的根本原因(此时可见标签只有1个,合法的索引值只有0,赋值1超出范围自然无效)。
最小改动解决方案
不需要重构原有业务逻辑,只需要修改两处代码即可:
1. 调整标签切换事件的判断逻辑
放弃用TabIndex作为判断条件,改用直接匹配激活的页面对象(或页面的Tag属性),完全不受标签显隐的影响:
procedure TF_DatenErfassung.PageControl1Change(Sender: TObject); begin // 直接匹配设计时的页面对象,和可见顺序无关 if PageControl1.ActivePage = TabSheet0 then // TabSheet0为设计时第0个标签的Name DBNavigator1.DataSource := F_ModuleTables.DS_MieteBezahlung else if PageControl1.ActivePage = TabSheet1 then // TabSheet1为设计时第1个标签的Name DBNavigator1.DataSource := F_ModuleTables.DS_T_JaresAbrechnung_Mieter; // 其余标签页按相同规则补充判断即可 end;
如果想保留原有的case结构,可以提前给每个标签页的Tag属性赋值为设计时的固定索引(比如第0个标签Tag设为0,第1个设为1,以此类推),调整代码为:
procedure TF_DatenErfassung.PageControl1Change(Sender: TObject); begin case PageControl1.ActivePage.Tag of 0: DBNavigator1.DataSource := F_ModuleTables.DS_MieteBezahlung; 1: DBNavigator1.DataSource := F_ModuleTables.DS_T_JaresAbrechnung_Mieter; // 其余标签对应补充分支即可 end; end;
2. 调整标签激活的赋值方式
不要用ActivePageIndex指定激活页,直接通过Pages数组指定页面对象,不受可见索引影响:
if ModuleTables.T_TABLE.FieldByName('NrDossier').AsString[1] <> 'X' then {A} begin PageControl1.Pages[0].TabVisible:=false; PageControl1.Pages[1].TabVisible:=true; // 直接指定激活的页面对象,不需要关心可见索引 PageControl1.ActivePage := PageControl1.Pages[1]; end else {B} begin PageControl1.Pages[0].TabVisible:=true; PageControl1.Pages[1].TabVisible:=false; PageControl1.ActivePage := PageControl1.Pages[0]; end;
对应7个标签的场景也完全适用:另一类场景下要显示设计时索引为6、7的标签,只需要把其余标签的TabVisible设为false,再指定ActivePage := PageControl1.Pages[6]即可。
内容的提问来源于stack exchange,提问作者Aorangi
相关产品推荐
相关产品推荐

