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黑色背景的主要内容,如果未能解决你的问题,请参考以下文章

IDEA中怎么设置黑色或白色背景

Qt 5.1.1 中设置背景,背景为黑色,怎么解决?

eclipse怎么换成黑色的背景

透明背景在 WPF 中变黑

所选 RibbonTab 的不同背景颜色

NSTextField - 黑色背景上的白色文本,但黑色光标