如何在执行Application.Run(form1)时隐藏form1?

3


我有一个使用Application.Run运行的表单1。

我想隐藏这个表单(我需要它隐藏,因为我在后台运行一些东西,所以它们必须执行),并打开另一个用于登录的表单。

我的尝试是在我的表单1构造函数中执行命令this.Hide();,如果登录成功,则显示我的表单1,但似乎不起作用。有任何想法吗?


this.Hide() 对我起作用,我们需要一个能重现问题的代码示例... - digEmAll
我不知道该给你什么代码。在 Program.cs 中执行了标准的 Application.Run(form),并且在窗体的构造函数中有一个 this.Hide()。 - Alex
你是在 Form1 的构造函数中执行后台任务吗?(可能是在调用 this.Hide() 之前?) - gideon
我正在另一个线程中执行我的后台任务,并将数据发送到我的Form1。 - Alex
可能是C# Hide new Form at start的重复问题。 - Hans Passant
7个回答

9

只需重写OnVisibleChanged方法并在其中更改窗体的可见性,类似于以下内容:

protected override void OnVisibleChanged(EventArgs e)
{
    base.OnVisibleChanged(e);
    this.Visible = false;
}

就是这样!简单而干净。


我现在正在使用它,它能够很好地工作,但是如果我想打开它,我找不到这个正在运行的应用程序?当我使用你的方法时,在任务管理器中可以看到它正在运行,但我无法找到它在哪里运行。 - Jim Vercoelen

2
看这个:使用ApplicationContext类完全封装启动屏幕功能 它基本上讲述了如何先显示一个启动屏幕,然后在加载完成后如何调用主窗体。(如果你在后台执行某些操作时隐藏了主窗体,请考虑使用启动屏幕)
引言中的引用:“这不是一个创建应用程序启动屏幕的示例。本文解释了一种将启动屏幕功能封装到继承的ApplicationContext类中的清晰方法。本文还详细介绍了WinForm应用程序启动时发生的情况。”

2
您可以在Form1类中重写SetVisibleCore,以使Form1实例在启动时隐藏。因此,这是一个示例,它将隐藏并保持表单隐藏状态,当然,您应该添加一些逻辑来决定何时实际允许表单变为可见。
public partial class Form1 : Form 
{ 
  public Form1() 
  { 
    InitializeComponent(); 
  } 

  protected override void SetVisibleCore(bool value) 
  {       
    // Quick and dirty to keep the main window invisible
    // you can put some logic here to decide when to use the
    // incomming value and when to force it to be false as I 
    // am showing here.       
    base.SetVisibleCore(false); 
  } 
} 

这是一个简单的例子,虽然有些牵强。Form1 开始时不可见,显示 Form2;当 Form2 关闭后,Form1 变为可见并显示该窗体。
using System;
using System.Windows.Forms;

namespace HideMainWinForm
{
  public partial class Form1 : Form
  {
    // Initially the main form cannot show
    private bool _canShow = false; 

    public Form1()
    {
      InitializeComponent();

      Form2 frm = new Form2();
      frm.FormClosed += new FormClosedEventHandler(frm_FormClosed);
      frm.Show();      
    }

    void frm_FormClosed(object sender, FormClosedEventArgs e)
    {
      // Once Form2 is closed we now allow the main form to
      // become visible.
      _canShow = true;
      this.Show();
    }

    protected override void SetVisibleCore(bool value)
    {
      base.SetVisibleCore(_canShow && value);
    }
  }
}

@Badescu Alexandru,是什么出了问题?表单没有隐藏吗?您能分享一下您尝试的方法吗? - Chris Taylor
public Form1(){ InitializeComponent(); SetVisibleCore(false); logIn li = new logIn(this); li.Show(); } - Alex
我使用了你的函数,除了在base.SetVisibleCore(false)里面的"false"之外,我加入了布尔值"value"。 - Alex
@Badescu Alexandru,你不应该调用SetVisibleCore函数,框架会自动调用它。你只需要在函数中提供可见性逻辑即可。请参考我简化后的示例。 - Chris Taylor
如果您在一个新的测试应用程序中使用第二个示例中的代码,它是否会按照您的预期工作? - Chris Taylor
这是正确的想法,但 Handle 不会被创建。请参见 https://dev59.com/xErSa4cB1Zd3GeqPavic#1953721。 - Hans Passant

0

如果您需要在显示表单之前进行一些后台工作,我建议有两种可能的选择。

第一种方法是,在创建表单并调用Application.Run之前,简单地执行您的后台工作。

第二种选择是,如果您需要在执行后台工作时保持消息循环处于活动状态,则可以使用不带From参数的Application.Run重载,并在您想要的时间准确地显示您的表单。唯一的问题是,当您想要结束应用程序时(因为它没有一个可以观察其关闭事件的表单),您将不得不手动调用Application.ExitApplication.ExitThread

因此,您的代码可能如下所示:

void Main()
{
    // trigger some background work
    ...

    // and start the message pump
    Application.Run();
}


void SomeBackgroundWork()
{
    // let's say now you completed the background work and you want to show your main Form
    MyForm f = new MyForm();
    f.Close += delegate { Application.Exit(); };
    f.Show();
}

如有需要澄清的地方,请留言评论...

问题在于我正在从一个线程向我的表单发送数据,所以我永远无法退出它,因此第一种选项失效了(因为有一个连续的流,所以我的程序经常接收数据),而第二种选项不是有效的,因为我需要表单多次进入“隐藏模式”,因为用户可以随意登录和注销,关闭应用程序并重新启动它不是一个选项。 - Alex

0
问题如下:
在构造函数中调用this.Hide()实际上设置了this.Visible = false,但是在窗体实例化后立即调用form.Show(由Application.Run调用),并且form.Show内部设置了this.Visible = true(当然与Hide相反...)。
你可以这样做:
private bool firstShow = true;

protected override void OnShown(EventArgs e)
{
    if (firstShow)
    {
        this.Hide();
        firstShow = false;
        return;
    }
    base.OnShown(e);
}

表单将会出现一瞬间,然后立即消失。

布尔标志firstShow允许您仅在第一次调用Show()时隐藏表单,而对于以下的调用,它将像平常一样工作。


0

Windows Forms有一个非常适合此类问题的事件,称为Form.Shown。每个Form对象仅在首次显示时调用一次。基本上这就是digEmAll的答案,但已经内置了。

在构造函数中添加一个由Form1.Shown调用的事件处理程序,然后在处理程序中调用Hide()

public form1()
{
    InitializeComponent()
    this.Shown += new EventHandler(form1_Shown);
    // call splash page
}

void form1_Shown(object sender, EventArgs e)
{
    this.Hide()
}

0
你可以使用这种方式。但是,你必须注意使用await和async的方法。
protected override void OnVisibleChanged(EventArgs e){
    base.OnVisibleChanged(e);
    this.Visible = false;
}

使用(await和async)的方法必须在形式初始化中包含(result)这个单词。

例如:

public frmForm1() {
    InitializeComponent();
    try {
        if (Program.LaunchedViaStartup == true) {
            var varclsReturnBack = funcStartBackGroundObjectsAsync().Result;
        }
    } catch (Exception varException) {
        Console.Write(varException.Message);
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接