显示隐形窗口

时间:2017-05-26 19:52:37

标签: c# wpf winforms

我有一个带有一些进程和可视化的窗口但是我希望这个窗口在启动时隐藏但仍然执行它的工作。我已经设法使用简单的代码

实现了这一目标
SomeWindow.Show();
SomeWindow.Hide();

但问题是此代码导致启动闪烁。我既不能在Windows窗体中也不能在WPF中解决这个问题。是否有更优雅的方式来显示隐藏/隐形窗口?

更新

我希望窗口在TaskBar中显示,但只有在它可见时才显示。窗口正在执行任务,该任务依赖于将在不管可见性的情况下及时执行的渲染,并且用户应该能够看到它一直处于打开状态。

5 个答案:

答案 0 :(得分:2)

试试这个:

SomeWindow.ShowInTaskbar = false; // not shown on taskbar set to true if you want to show form on taskbar
SomeWindow.WindowState = FormWindowState.Minimized; // set window state as minimized
SomeWindow.Show(); 

你甚至不需要隐藏它。

这是winforms版本,我没有在WPF中测试它。

更新

如果在Hide()窗口打开的窗口列表(Alt + Tab)后未执行Show()。为了防止这种情况:

SomeWindow.Hide(); 

答案 1 :(得分:1)

基于Logman's answer我创建了展示隐形窗口的扩展方法

对于Windows窗体:

public static class FormHelper
{
    public static void ShowInvisible(this Form form)
    {
        // saving original settings
        bool needToShowInTaskbar = form.ShowInTaskbar;
        FormWindowState initialWindowState = form.WindowState;

        // making form invisible
        form.ShowInTaskbar = false;
        form.WindowState = FormWindowState.Minimized;

        // showing and hiding form
        form.Show();
        form.Hide();

        // restoring original settings
        form.ShowInTaskbar = needToShowInTaskbar;
        form.WindowState = initialWindowState;
    }
} 

或WPF:

public static class WindowHelper
{
    public static void ShowInvisible(this Window window)
    {
        // saving original settings
        bool needToShowInTaskbar = window.ShowInTaskbar;
        WindowState initialWindowState = window.WindowState;

        // making window invisible
        window.ShowInTaskbar = false;
        window.WindowState = WindowState.Minimized;

        // showing and hiding window
        window.Show();
        window.Hide();

        // restoring original settings
        window.ShowInTaskbar = needToShowInTaskbar;
        window.WindowState = initialWindowState;
    }
}

答案 2 :(得分:0)

为什么要使用窗口执行此任务?为什么不在另一个线程上启动一个类并让它完成工作呢?

如果确实需要一个窗口,只需在打开请求来自该自定义任务的数据时使用该窗口。

var myClass = new MyClass();

Task.Run(()=>myClass.Start());

答案 3 :(得分:0)

这适用于没有“闪烁”的机器。正如Ed所提到的,任务栏按钮的行为与没有添加设置或代码的情况一样。

//Assuming SomeWindow is System.Windows.Form object
SomeWindow.Opacity = 0.0;
SomeWindow.Show();
SomeWindow.Hide();

//Elsewhere in code when you want to display the window
SomeWindow.Opacity = 1.0;
SomeWindow.Visible = true;

答案 4 :(得分:0)

Vadim Ovchinnikov's answer对于WPF来说是一个不错的开始,但最终对我不起作用有两个原因:Show()和Hide()是同步方法,当您希望在创建窗口时预先创建时,这是一个问题没有打开其他窗口(因为没有分派器执行这些请求);此外,还必须稍后执行恢复原始值的操作,否则仍然会出现快速闪烁。再一次,我不得不异步地恢复ShowInTaskbar的值。否则,任务栏条目将丢失,但奇怪的是,仅当在Visual Studio调试器中运行时。

以下帮助类为我完成了工作:

public class InitiallyInvisibleWindow
{
  private readonly Window _window;
  private bool _origShowActivated;
  private bool _origShowInTaskbar;
  private WindowState _origWindowState;

  public InitiallyInvisibleWindow(Window window)
  {
    _window = window;
  }

  public void ShowInvisible()
  {
    _origShowActivated = _window.ShowActivated;
    _origShowInTaskbar = _window.ShowInTaskbar;
    _origWindowState = _window.WindowState;

    _window.ShowActivated = false;
    _window.ShowInTaskbar = false;
    _window.WindowState = WindowState.Minimized;

    _window.Visibility = Visibility.Visible;
    _window.Visibility = Visibility.Hidden;
  }

  public void RestoreVisible()
  {
    _window.ShowActivated = _origShowActivated;
    _window.Visibility = Visibility.Visible;

    Dispatcher.CurrentDispatcher.InvokeAsync(() =>
      {
        _window.ShowInTaskbar = _origShowInTaskbar;
        _window.WindowState = _origWindowState;
      });
  }
}