当子窗体处于活动状态时,如何禁用父窗体?


73

使用C#激活子窗体时,如何禁用父窗体?


您不能只使用ChildForm.show然后再使用Mainform.disable / .hide,还是要谈论同时激活2个表单,而当子表单(激活以禁用主表单)然后打开(不集中)时重新激活mainforM ?
唐·汤玛斯·博伊尔

@DonThomasBoyle:嘿,我正在寻找您所描述的解决方案“同时激活2种表单,而当子表单处于激活状态(禁用主菜单)然后启用(散焦)重新激活mainforM”可以给我吗?提示如何解决?我已经尝试了线程,application.run等,但没有任何效果。您将如何实现?
メロディア

Answers:


188

您是否尝试过使用Form.ShowDialog()而不是Form.Show()

ShowDialog将您的窗口显示为模式窗口,这意味着您无法与父窗体进行交互,直到其关闭。


这不会隐藏父表单吗?
barlop

@barlop隐藏this.Hide()父表单代码中的父表单用法。
vee'Mar

@vee你误解了我。我在问为什么似乎要隐藏它(当我不想隐藏它时)。我的问题已解决,是这个stackoverflow.com/questions/38171607/…–
barlop

谢谢@R。Martinho Fernandes,这很好用!
杰米·奥耶比西

37

您是在打电话ShowDialog()还是Show()在父母表格的孩子表格上打电话?

ShowDialog将“阻止”用户与作为参数传递给的表单进行交互ShowDialog

在父母中,您可能会这样称呼:

MyChildForm childForm = new MyChildForm();

childForm.ShowDialog(this);

this父表单在哪里。


为我工作!VB.Net的版本是这样的:Public childForm As New ChildformclasschildForm.ShowDialog(Me)其中Me是类的父(母型)非常感谢你@Philip
伊格纳西奥·布斯托斯


10

可以做的是,在显示子表单时确保将父表单作为所有者传递:

  Form newForm = new ChildForm();
  newForm.Show(this);

然后,在子窗体中,为ActivatedDeactivate事件设置事件处理程序:

private void Form_Activated(object sender, System.EventArgs e)
{
    if (this.Owner != null)
    {
        this.Owner.Enabled = false; 
    }
}

private void Form_Deactivate(object sender, System.EventArgs e)
{
    if (this.Owner != null)
    {
        this.Owner.Enabled = true;
    }
}

但是,这将导致真正的异常行为。虽然您将无法返回并立即与父表单进行交互,但是激活任何其他应用程序将使其启用,然后用户可以与其进行交互。

如果要使子窗体为modal,请使用ShowDialog

  Form newForm = new ChildForm();
  newForm.ShowDialog(this);

如果要在子窗体的生命周期中禁用父窗体,则无论其他窗体或同时处于激活状态的应用程序如何,也可以处理Form_Closed而不是Form_Deactivate。
JamesFaix

8

虽然使用前面提到的childForm.ShowDialog(this)将禁用您的主窗体,但它看起来确实仍然非常禁用。但是,如果在ShowDialog()之前调用Enabled = false,在ShowShow()之后调用Enable = true,则主窗体甚至看起来已被禁用。

var childForm = new Form();
Enabled = false;
childForm .ShowDialog(this);
Enabled = true;

我看不到它如何工作..当我尝试它时,它隐藏了父窗体
barlop



4

@梅洛迪亚

抱歉,这不是C#代码,但这是您想要的,除了翻译之外,这应该很容易。

表格1

Private Sub Form1_MouseEnter(sender As Object, e As EventArgs) Handles MyBase.MouseEnter
    Me.Focus()
    Me.Enabled = True
    Form2.Enabled = False
End Sub

Private Sub Form1_MouseLeave(sender As Object, e As EventArgs) Handles MyBase.MouseLeave
    Form2.Enabled = True
    Form2.Focus()
End Sub

表格2

Private Sub Form2_MouseEnter(sender As Object, e As EventArgs) Handles MyBase.MouseEnter
    Me.Focus()
    Me.Enabled = True
    Form1.Enabled = False
End Sub

Private Sub Form2_MouseLeave(sender As Object, e As EventArgs) Handles MyBase.MouseLeave
    Form1.Enabled = True
    Form1.Focus()
End Sub

希望这可以帮助


非常感谢!你的想法很棒!我刚刚发现它也可以通过与表格父母一起工作并将孩子与他们对接来工作。
2013年

4

您可以执行以下操作:

Form3 formshow = new Form3();

formshow.ShowDialog();

2

您也可以使用MDIParent-child形式。将子窗体的父级设置为MDI父级

例如

child.MdiParent = parentForm;
child.Show();

在这种情况下,将仅显示1个表单,而子表单将进入父表单。希望这可以帮助


1

对我来说,例如,在打开注册表时,将禁用主菜单。

 frmUserRegistration frmMainMenu = new frmUserRegistration();
    frmMainMenu.ShowDialog(this);

1

如果您只是想模拟Form.ShowDialog调用而没有阻塞任何东西(有点像模拟对话框表单),则可以尝试使用Form.Show(),并在显示模拟对话框表单后立即使用禁用所有其他窗口就像是...

private void DisableAllWindows()
{
foreach (Form f in Application.OpenForms)
if (f.Name != this.Name)f.Enabled = false;
else f.Focus();
}

然后,当您关闭“伪对话框”​​时,请确保调用...。

private void EnableAllWindows()
{
foreach (Form f in Application.OpenForms) f.Enabled = true;
}

-2

为什么不让父母等孩子关闭呢?这超出了您的需要。

// Execute child process
System.Diagnostics.Process proc = 
    System.Diagnostics.Process.Start("notepad.exe");
proc.WaitForExit();

1
-1:您从来都不敢在单击/按下/鼠标/键处理程序中执行此操作。信息:stackoverflow.com/questions/470256/…–
quetzalcoatl

这个答案是关于过程的,而不是关于形式的。对某人有用,但不能解决该问题。如果在GUI线程上完成操作,这也是一个非常糟糕的主意-您的应用程序GUI将被锁定,直到其他进程返回为止-如果发生任何错误,用户将不得不求助于任务管理器以终止您的应用程序。小心使用!甚至更好:使用一些异步解决方案,而不是WaitForExit。
制造商史蒂夫(Steve)2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.