从子表单启用父表单

时间:2013-04-07 08:26:40

标签: c# winforms

情况是我有父表单,每次点击search button搜索表单父表单 em>只是已禁用,但可以看到

每次我点击搜索表单上的exit button 搜索表单退出时,问题就出现了,但是父表单MainForm 仍然停用

搜索表单上的exit button上的代码

MainForm mainForm = new MainForm();
mainForm.Enabled = true;
this.Hide();

4 个答案:

答案 0 :(得分:1)

您的代码会创建MainForm类的新实例。这个新实例不是启动搜索表单的原始实例。显而易见,第一个实例仍然被禁用,而新的实例仍然启用,但由于未显示而无法看到它

通常这个问题可以通过各种方式解决。

  • 传递打开搜索表单的表单实例(MainForm) 到搜索表单
  • 注册搜索表单关闭时要通知的主实例
  • 创建并引发您自己的事件,向外部表单发出信号 搜索已结束

如何注册要通知SearchForm关闭的MainForm
启动搜索表单的MainForm代码应该更改为这样的代码 编辑此方法要求您有效关闭SearchForm。简单的隐藏不会关闭表单,因此SearchForm

不会引发任何结束事件
SearchForm f = new SearchForm();
// Here the current (this) instance of the MainForm requires 
// to be notified of the closing of the search form
f.Closing += new System.ComponentModel.CancelEventHandler(OnSearchClosing);
this.Enabled = false;
f.Show();
....

并添加此代码以在搜索表单关闭时收到通知

// When the search form closes you get this event 
// Here `this` is the correct instance of the MainForm (the one disabled)
private void OnSearchClosing(object sender, System.ComponentModel.CancelEventArgs e)
{
    this.Enabled = true;
}

如何传递调用SearchForm实例的MainForm实例
在我看来,第二种方法不太可取,因为您将强制搜索表单引用主表单,您将从SearchForm操作MainForm。
通过这种方式,您将MainForm的引用传递给SearchForm,并使用该引用重新启用mainForm

// In the calling code of the search form pass the reference to the caller
SearchForm f = new SearchForm(this);
f.Show();

在SearchForm的表单构造函数中,接收引用并存储在全局类变量

public class SearchForm:Form
{
    private MainForm _callerForm;
    public void SearchForm(MainForm callingForm)
    {
         InitializeComponent();
         _callerForm = callingForm;
         _callerForm.Enabled = false;
    }

    // ...  somewhere in this class
    _callerForm.Enabled = true;
    this.Hide();
    // ....
}

如何创建和提升自定义事件
第三种方法具有第一种方法的好处,并将通知的责任留在开发人员手中(这意味着您可以提出自己的事件,并且对事件感兴趣的任何人都可以处理自己的业务)< / p>

在SearchForm中创建自定义事件

在SearchForm.cs中

// Build a delegate that returns nothing and receive nothing
// Define an event based on that delegate
public delegate void OnSearchEnded();
public event OnSearchEnded SearchEnded;

... somewhere in this class
// If some external entity choose to be notified when whe have finished search
// raise the event to which this external entity has subscribed (MainForm)
if(SearchEnded != null)
    SearchEnded();
    ....
MainForm.cs中的

SearchForm f = new SearchForm();
// Here the current (this) instance of the MainForm infom the SearchForm 
// that it wants to be notified when the search end
f.SearchEnded += new SearchForm.OnSearchEnded(EnableThisForm);
this.Enabled = false;
f.Show();
....

// Here the main form receives the notification from the Search Form
public void EnableThisForm()
{
   this.Enabled = true;
}

答案 1 :(得分:1)

更优雅的解决方案是使搜索形成模态对话框。无论何时打开模态对话框,其父表单都会自动禁用。

您可以通过将创建搜索表单的父表单上的代码更改为:

来执行此操作
searchform.ShowDialog(this);

这将禁用父表单,直到搜索表单关闭,然后父表单将自动重新启用。

答案 2 :(得分:0)

您应该将MainForm传递给SearchForm,这样在关闭搜索表单之前,您将能够隐藏原始MainForm而无需创建新的MainForm。请参阅下面的代码:

public class MainForm:Form
{
    private SearchForm searchForm;//for keeping the search form
    public MainForm()//your main form constructor
    {

    }
    this.searchBtn.Click+=(s,e)=>
    {
        if(this.searchForm == null)
        {
            this.searchForm = new SearchForm(this);//creating new searchForm if it does no exist
            this.searchForm.Show();
            this.Enabled = false;
        }

    };

}

public class SearchForm:Form
{
    private MainForm mainForm;//this will keep the original mainform
    public SearchForm(MainForm mainForm)
    {
        this.mainForm = mainForm;
    }

    this.OnFormClosing+=(s,e)=>
    {
        this.mainForm.Enabled = true;   
    };
}

这将每次关闭搜索表单,并在您单击搜索按钮时创建它的新实例。如果你想隐藏它,你应该使用这个代码:

public class MainForm:Form
{
    private SearchForm searchForm;//for keeping the search form
    public MainForm()//your main form constructor
    {

    }
    this.searchBtn.Click+=(s,e)=>
    {
        if(this.searchForm == null)
        {
            this.searchForm = new SearchForm(this);//creating new searchForm if it does no exist
            this.searchForm.Show();
            this.Enabled = false;
        }
        else
        {
            this.Enabled = false;
            this.searchForm.Show();
        }

    };

}

public class SearchForm:Form
{
    private MainForm mainForm;//this will keep the original mainform
    public SearchForm(MainForm mainForm)
    {
        this.mainForm = mainForm;
    }

    this.OnFormClosing+=(s,e)=>
    {
        e.Cancel = true;
        this.mainForm.Enabled = true;   
        this.Hide();
    };
}

基本上这是在没有复杂事件的情况下执行此操作的最简单方法,等等。我希望这可以解决你的问题,如果不是我来帮忙。

答案 3 :(得分:0)

UpgradeLicenseDialog dialogBox = new UpgradeLicenseDialog();
dialogBox.FormClosing+=dialogBox_FormClosing;
dialogBox.StartPosition = FormStartPosition.CenterScreen;
this.Enabled = false;
dialogBox.Show();`

使用clossing事件启用父...

  

private void dialogBox_FormClosing(object sender,System.ComponentModel.CancelEventArgs e)           {               this.Enabled = true;           }