兩個可能的解決方案是:
1)直接回答這個問題,一個可能的解決方案是使用的ShowDialog()(未在事件處理程序),而不是顯示()
這樣做:
namespace formSwitchTest
{
ref class tcFormBase : System::Windows::Forms::Form
{
public:
tcFormBase(
System::String^aTitle,
System::Windows::Threading::Dispatcher^aMainDispatcher) :
mpcForm(nullptr),
mMainDispatcher(aMainDispatcher)
{
this->SuspendLayout();
this->AutoSize = true;
mpcSwitchButton = gcnew System::Windows::Forms::Button();
mpcSwitchButton->AutoSize = true;
mpcSwitchButton->Click += gcnew System::EventHandler(this, &formSwitchTest::tcFormBase::ButtonClicked);
mpcSwitchButton->Text = "Click to leave ";
mpcSwitchButton->Text += aTitle;
mpcSwitchButton->Dock = System::Windows::Forms::DockStyle::Top;
mpcExitButton = gcnew System::Windows::Forms::Button();
mpcExitButton->AutoSize = true;
mpcExitButton->Click += gcnew System::EventHandler(this, &formSwitchTest::tcFormBase::Exit);
mpcExitButton->Text = "click to exit";
mpcExitButton->Dock = System::Windows::Forms::DockStyle::Bottom;
mpcTextBox = gcnew System::Windows::Forms::TextBox();
mpcTextBox->Width = 200;
mpcTextBox->AutoSize = true;
mpcTextBox->Text = "enter text here";
mpcTextBox->Dock = System::Windows::Forms::DockStyle::Left;
this->Controls->Add(mpcTextBox);
this->Controls->Add(mpcSwitchButton);
this->Controls->Add(mpcExitButton);
this->ResumeLayout();
this->PerformLayout();
}
void SetOtherForm(System::Windows::Forms::Form^apcForm)
{
mpcForm = apcForm;
// save this action to perform multiple times later
mShowOtherForm = gcnew System::Action(this, &formSwitchTest::tcFormBase::ShowOtherForm);
}
void ShowDialog()
{
System::Windows::Forms::Form::ShowDialog();
}
private:
void ShowOtherForm()
{
// perform the blocking ShowDialog() because it works better than Show()
mpcForm->ShowDialog();
}
void Exit(System::Object^apcSender, System::EventArgs^apcArgs)
{
// stop the blocking ShowDialog()
this->Hide();
// tell the dispatcher to stop, which will stop the Run() call
mMainDispatcher->BeginInvokeShutdown(System::Windows::Threading::DispatcherPriority::Normal);
}
void ButtonClicked(System::Object^apcSender, System::EventArgs^apcArgs)
{
// stop the blocking ShowDialog()
this->Hide();
// BeginInvoke() to prevent blocking
mMainDispatcher->BeginInvoke(mShowOtherForm);
}
System::Windows::Forms::Form^mpcForm;
System::Windows::Forms::Button^mpcSwitchButton;
System::Windows::Forms::Button^mpcExitButton;
System::Windows::Forms::TextBox^mpcTextBox;
System::Windows::Threading::Dispatcher^mMainDispatcher;
System::Action^mShowOtherForm;
};
}
int main(void)
{
System::Windows::Threading::Dispatcher^lpcMainDispatcher =
System::Windows::Threading::Dispatcher::CurrentDispatcher;
// the only reason for each form being of the same base is for ease of the test
formSwitchTest::tcFormBase^lpcMainForm = gcnew formSwitchTest::tcFormBase(
"main", lpcMainDispatcher);
formSwitchTest::tcFormBase^lpcSecondForm = gcnew formSwitchTest::tcFormBase(
"second", lpcMainDispatcher);
// exchange pointers to each other
lpcMainForm->SetOtherForm(lpcSecondForm);
lpcSecondForm->SetOtherForm(lpcMainForm);
// begin invoke to put the start action in the queue
lpcMainDispatcher->BeginInvoke(gcnew System::Action(lpcMainForm, &formSwitchTest::tcFormBase::ShowDialog));
// process the dispatcher queue and wait for it to be shut down
System::Windows::Threading::Dispatcher::Run();
}
2)它可能會更好,更接近你在找什麼使用控件類,而不是形式
namespace formSwitchTest
{
ref class tcCtrlBase : System::Windows::Forms::UserControl
{
public:
tcCtrlBase(
System::String^aTitle,
System::Windows::Forms::Form^apcContainerForm) :
mpcCtrl(nullptr),
mpcContainerForm(apcContainerForm)
{
this->SuspendLayout();
this->AutoSize = true;
mpcSwitchButton = gcnew System::Windows::Forms::Button();
mpcSwitchButton->AutoSize = true;
mpcSwitchButton->Click += gcnew System::EventHandler(this, &formSwitchTest::tcCtrlBase::ButtonClicked);
mpcSwitchButton->Text = "Click to leave ";
mpcSwitchButton->Text += aTitle;
mpcSwitchButton->Dock = System::Windows::Forms::DockStyle::Top;
mpcExitButton = gcnew System::Windows::Forms::Button();
mpcExitButton->AutoSize = true;
mpcExitButton->Click += gcnew System::EventHandler(this, &formSwitchTest::tcCtrlBase::Exit);
mpcExitButton->Text = "click to exit";
mpcExitButton->Dock = System::Windows::Forms::DockStyle::Bottom;
mpcTextBox = gcnew System::Windows::Forms::TextBox();
mpcTextBox->Width = 200;
mpcTextBox->AutoSize = true;
mpcTextBox->Text = "enter text here";
mpcTextBox->Dock = System::Windows::Forms::DockStyle::Left;
this->Controls->Add(mpcTextBox);
this->Controls->Add(mpcSwitchButton);
this->Controls->Add(mpcExitButton);
this->ResumeLayout();
this->PerformLayout();
}
void SetOtherCtrl(System::Windows::Forms::UserControl^apcCtrl)
{
mpcCtrl = apcCtrl;
}
private:
void ShowOtherForm()
{
mpcCtrl->Show();
}
void Exit(System::Object^apcSender, System::EventArgs^apcArgs)
{
mpcContainerForm->Hide();
}
void ButtonClicked(System::Object^apcSender, System::EventArgs^apcArgs)
{
this->Hide();
mpcCtrl->Show();
}
System::Windows::Forms::UserControl^mpcCtrl;
System::Windows::Forms::Button^mpcSwitchButton;
System::Windows::Forms::Button^mpcExitButton;
System::Windows::Forms::TextBox^mpcTextBox;
System::Windows::Forms::Form^mpcContainerForm;
};
}
int main(void)
{
System::Windows::Forms::Form^lpcContainerForm = gcnew System::Windows::Forms::Form();
formSwitchTest::tcCtrlBase^lpcMainForm = gcnew formSwitchTest::tcCtrlBase(
"main", lpcContainerForm);
formSwitchTest::tcCtrlBase^lpcSecondForm = gcnew formSwitchTest::tcCtrlBase(
"second", lpcContainerForm);
lpcMainForm->SetOtherCtrl(lpcSecondForm);
lpcSecondForm->SetOtherCtrl(lpcMainForm);
lpcContainerForm->AutoSize = true;
lpcContainerForm->Controls->Add(lpcMainForm);
lpcContainerForm->Controls->Add(lpcSecondForm);
lpcContainerForm->ShowDialog();
}