在 TabSheet1Show 中向 TPageControl 添加控件

Adding controls to TPageControl within TabSheet1Show

当我尝试在运行时向已存在的 TTabSheet 添加控件时,这些控件在 TTabSheetOnShow 事件中添加时保持不可见。

重现步骤:

  1. 在设计器中将 TPageControl 添加到 TForm
  2. 在设计器中向此 TPageControl 添加 3 TTabSheet 个对象。
  3. 设置第一个 TTabSheet 活动(在设计时)。
  4. 运行 代码如下:

头文件:

#ifndef Unit1H
#define Unit1H

#include <System.Classes.hpp>
#include <Vcl.Controls.hpp>
#include <Vcl.StdCtrls.hpp>
#include <Vcl.Forms.hpp>
#include <Vcl.ComCtrls.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published:    // Von der IDE verwaltete Komponenten
    TPageControl *PageControl1;
    TTabSheet *TabSheet1;
    TTabSheet *TabSheet2;
    TTabSheet *TabSheet3;
    TButton *Button1;
    void __fastcall TabSheet1Show(TObject *Sender);
private:    // Benutzer-Deklarationen
    TButton *ButtonConstructor;
    TButton *ButtonOnTabShow;
public:     // Benutzer-Deklarationen
    __fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif

源文件:

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
    // Adding a TButton in the Form's constructor works

    TTabSheet *ts = this->TabSheet1;

    if (!this->ButtonConstructor)
    {
        ButtonConstructor = new TButton( ts );
        ButtonConstructor->Name = "ButtonConstructor";
        ButtonConstructor->Caption = "Construct";
        ButtonConstructor->Parent = ts;
    }


}
//---------------------------------------------------------------------------
void __fastcall TForm1::TabSheet1Show(TObject *Sender)
{
    // Adding a TButton in the OnShow Event of TTabSheet does NOT work:
    // The button stays invisible

    TTabSheet *ts = dynamic_cast< TTabSheet * >( Sender );
    // TTabSheet *ts = this->ButtonOnTabShow;   // does not make any difference

    if (!this->ButtonOnTabShow)
    {
        ButtonOnTabShow = new TButton( ts );
        ButtonOnTabShow->Name = "ButtonOnTabShow";
        ButtonOnTabShow->Caption = "Show";
        ButtonOnTabShow->Parent = ts;
        // Button should be placed below the other
        ButtonOnTabShow->Top = ButtonConstructor->Top + ButtonConstructor->Height + 2;
    }

    // The following 2 lines would make the Button visible
    // PageControl1->ActivePageIndex = 1;
    // PageControl1->ActivePageIndex = 0;
}

结果是:

如果您点击 TabSheet2 然后返回 TabSheet1ButtonOnTabShow 也将可见。

这是一个无法解决的错误,还是我遗漏了什么?

我不确定为什么会发生这种情况,但我可以重现它。它可能与 TPageControl 管理其 TTabSheet 对象可见性的方式有关(因为 Win32 API 没有标签页的概念。TTabSheet 完全是 VCL 的发明以简化选项卡式内容的管理)。但是,使用此代码很容易变通:

#define WM_ENSUREBUTTONSHOWN (WM_APP+1)

void __fastcall TForm1::TabSheet1Show(TObject *Sender)
{
    // ...

    if (!this->ButtonOnTabShow)
    {
        ButtonOnTabShow = new TButton( ts );
        // ...
        PostMessage(Handle, WM_ENSUREBUTTONSHOWN, 0, 0);
    }
}

void __fastcall TForm1::WndProc(TMessage &Message)
{
    TForm::WndProc(Message);
    if ((Message.Msg == WM_ENSUREBUTTONSHOWN) && (this->ButtonOnTabShow))
    {
        this->ButtonOnTabShow->Hide();
        this->ButtonOnTabShow->Show();
    }
}

或者:

#define WM_REFRESHTABSHEET (WM_APP+1)

void __fastcall TForm1::TabSheet1Show(TObject *Sender)
{
    // ...

    if (!this->ButtonOnTabShow)
    {
        ButtonOnTabShow = new TButton( ts );
        // ...
        PostMessage(Handle, WM_REFRESHTABSHEET, 0, 0);
    }
}

void __fastcall TForm1::WndProc(TMessage &Message)
{
    TForm::WndProc(Message);
    if ((Message.Msg == WM_REFRESHTABSHEET) && (this->TabSheet1->Visible))
    {
        this->TabSheet1->Hide();
        this->TabSheet1->Show();
    }
}