WPF:MainWindow黑色背景
Posted
技术标签:
【中文标题】WPF:MainWindow黑色背景【英文标题】:WPF: MainWindow black background 【发布时间】:2018-10-19 18:35:30 【问题描述】:如果应用程序已经在运行并且用户尝试运行程序的新实例(单个实例),我正在尝试从系统托盘打开 MainWindow
我正在关注本教程: https://www.codeproject.com/Articles/32908/C-Single-Instance-App-With-the-Ability-To-Restore
如果 MainWindow 被最小化,它工作得很好,但是,当我关闭我只是隐藏的窗口,并通过传递消息(使用主窗口处理程序)从新创建的实例重新打开它时,我得到窗口打开,但它是一个黑屏。
关闭主窗口:
private void main_Closing(object sender, System.ComponentModel.CancelEventArgs e)
// If the window is visible, then hide it
if (IsVisible)
Visibility = Visibility.Hidden;
e.Cancel = true;
使用 MainWinow 处理程序显示 MainWindow
public const int SW_SHOWNORMAL = 1;
[DllImportAttribute("user32.dll")]
public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
[DllImportAttribute("user32.dll")]
public static extern bool SetForegroundWindow(IntPtr hWnd);
public static void ShowToFront(IntPtr window)
ShowWindow(window, SW_SHOWNORMAL);
SetForegroundWindow(window);
我如何在 MainWindow.xaml.cs 中调用它
public void ShowWindow()
WinApi.ShowToFront(new WindowInteropHelper(this).Handle);
我可以通过替换来获得正常的窗口
public void ShowWindow()
WinApi.ShowToFront(new WindowInteropHelper(this).Handle);
与
public void ShowWindow()
Visibility = Visibility.Visible;
WindowState = WindowState.Normal;
但是,我仍然想知道为什么 Handler 以黑屏打开我的 MainWindow ?
正常:
黑屏:
【问题讨论】:
可能是需要重新初始化组件 @John112358 我绑定在 ShowWindow() 函数中调用 InitializeCompnent() 但它不起作用。非常感谢您的回答 【参考方案1】:我没有直接回答您的问题,但我可以通过提出一种更简单的方法来解决您的问题来间接回答它,以避免大多数 WinForm、ptr 处理程序和导入所有 dll 的东西。 这种方法可以让你几乎只处理 WPF 代码,我测试过,不存在背景颜色问题
首先:在 MainWindow.xaml.cs 中
-
使 MainWindow 成为单例
与您所做的类似,在用户尝试关闭 MainWindow 时隐藏 MainWindow 而不是关闭它。
您的 MainWindow.xml.cs 应该如下所示,无需其他附加代码:
using System.Windows;
namespace WPFSystemTray
public partial class MainWindow : Window
private static MainWindow instance;
public static MainWindow Instance
get
if (instance == null)
instance = new MainWindow();
return instance;
private MainWindow()
InitializeComponent();
this.Closing += MainWindow_Closing;
private void MainWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e)
if (!App.IsExitApplication)
e.Cancel = true;
this.Hide();
第二:从App.xaml.cs中删除以下代码
StartupUri="MainWindow.xaml"
第三:将以下引用添加到你的WPF项目中
-
System.Drawing
System.Windows.Forms
第四:给资源添加图标
-
右键单击您的 WPF 项目并选择属性或双击您的 WPF 项目中的属性。
选择资源
选择图标
选择添加资源
选择添加现有文件...以从您的 PC 中选择或选择添加新图标以创建新图标。
如果您使用不同的图标,请确保将您的图标重命名为 Dapino-Summer-Holiday-Palm-tree.ico 或在 App.xaml.cs 中的代码中更改它
I got my test icon from this link
五:给资源添加图片
-
遵循上述相同的说明(第四部分)
确保将 Icons 更改为 Images
如果您选择不同的图像,请确保将其重命名为 palm-tree-icon.png 或确保在 App.xaml.cs 中的代码中更改名称强>
I got my test icon from this link
第六:App.xaml.cs
-
添加构造函数和启动方法。
创建应用和应用托盘的实例
在任务托盘中添加了两个项目(应用名称和退出)
其中一项带有图标,如果您不知道该怎么做。
您的 App.xaml.cs 应如下所示。
using System;
using System.Windows;
namespace WPFSystemTray
public partial class App : Application
public static bool IsExitApplication;
public App()
Startup += App_Startup;
private void App_Startup(object sender, StartupEventArgs e)
WPFSystemTray.MainWindow.Instance.Show();
System.Windows.Forms.NotifyIcon notifyIcon = new System.Windows.Forms.NotifyIcon();
notifyIcon.DoubleClick += _notifyIcon_DoubleClick;
notifyIcon.Icon = WPFSystemTray.Properties.Resources.Dapino_Summer_Holiday_Palm_tree;
notifyIcon.Visible = true;
CreateContextMenu(notifyIcon);
private void _notifyIcon_DoubleClick(object sender, EventArgs e)
ShowMainWindow();
private void CreateContextMenu(System.Windows.Forms.NotifyIcon notifyIcon)
if (notifyIcon != null)
notifyIcon.ContextMenuStrip = new System.Windows.Forms.ContextMenuStrip();
notifyIcon.ContextMenuStrip.Items.Add("Application Name",
WPFSystemTray.Properties.Resources.palm_tree_icon).Click
+= NotifyIcon_ApplicationName_Click;
notifyIcon.ContextMenuStrip.Items.Add("Exit").Click += NotifyIcon_Exit_Click;
private void NotifyIcon_ApplicationName_Click(object sender, EventArgs e)
ShowMainWindow();
private void NotifyIcon_Exit_Click(object sender, EventArgs e)
IsExitApplication = true;
MainWindow.Close();
(sender as System.Windows.Forms.ToolStripItem).Owner.Dispose();
public void ShowMainWindow()
if (!MainWindow.IsVisible)
MainWindow.Show();
else
if (MainWindow.WindowState == WindowState.Minimized)
MainWindow.WindowState = WindowState.Normal;
MainWindow.Activate();
构建和测试
-
首先,它将打开 MainWindow
要在托盘中进行选择,请右键单击图标并选择(应用名称或退出)。
双击图标将再次打开应用程序。 要将其更改为仅单击一次:将 notifyIcon.DoubleClick 更改为 App.xaml.cs 中的 notifyIcon.Click 事件>
我尽量减少更改,以便您更轻松地添加到项目中。
我希望您同意这比您在 codeproject.com 中遵循的示例更简单更好。
【讨论】:
当您说“双击图标”时,您是指系统托盘上的图标还是程序图标(如程序的新实例)。因为在我的问题中,我的意思是尝试你的程序的一个新进程,所以我要做的是让我的程序的新进程(即时)打开已经运行的实例的 MainWindow 杀死自己。这就是我使用处理程序的原因。 我的意思是在系统托盘中。是的,这就是你想要的。当您尝试从程序图标打开程序的新实例时,它将打开现有的先前实例(如果有的话)。如果它不存在(没有实例正在运行),它将创建一个新的。【参考方案2】:我无法明确记住何时何地,但隐藏一个窗口基本上会结束它的生命,例如模态窗口。当我需要做类似的事情时,我只是将 Window 的 LEFT 属性设置为一些淫秽的负值,而不是隐藏或使可见为假,这样用户就看不到了。
例如,您的实际窗口尺寸为 800x450。我可能会将我的 LEFT 位置设置为 -900。由于我的窗口在最坏情况下是 800 宽,向左移动 -900 不会使其可见,但也不会释放窗口及其资源。因此,当您尝试重置其可见性时,只需将其左侧位置设置回 0。现在,如果用户有多个监视器,那可能是一个不同的问题......也许将左侧设置为 -4000。
【讨论】:
这听起来像是一种 hacky 方式,但我肯定会完全考虑(这不像我反对 hacky 方式!)。非常感谢。 @Muhannad,是的,可能是一个 hack,但是如果你有一个模态窗口你想返回并隐藏它,它就会失去它的模态并终止它的读取状态。【参考方案3】:对于 WPF,执行此操作的方法要简单得多。
只需将激活的功能添加到您的 MainWindow 或您喜欢的其他表单中。
并添加 this.show();
public void Window_Activated(object sender, EventArgs e)
this.Show();
这对我有用。并且避免了冗长的编码。
【讨论】:
以上是关于WPF:MainWindow黑色背景的主要内容,如果未能解决你的问题,请参考以下文章