C# WSTO窗口焦點問題的解決辦法

原文地址:https://www.cnblogs.com/cplemom/p/11514668.html,感謝原作者,讓我少走不少彎路。
寫插件彈窗是肯定要有的,有彈窗纔有展示功能的頁面啊!
記錄一下前段時間遇到的一些彈窗方面的坑,一個個踩過來也是收穫頗豐啊!

1、WPF彈窗

最簡單的彈窗方式,new一個窗體,然後調用Show方法。

Window window = new Window();
window.Show();

然後根據需求的不一樣,就有一些東西要調整了,簡單一些的比如是否在任務欄顯示,是否允許最大最小化,是否運行拖拽等等

window.ShowInTaskbar = false;
window.ResizeMode = ResizeMode.NoResize;
window.AllowDrop = false;

像上面那樣一頓噼裏嘩啦操作。確實,彈窗出來了~但是點擊起來就有點不對勁了。每次點擊或焦點切換到主窗體的時候,彈窗都會被主窗體蓋住。
馬上想到了有一個解決方法,設置彈窗爲最頂層就ok了啊!就不用擔心被蓋住了。

window.Topmost = true;

果然達到了預期,哪怕焦點切換了,彈窗也還是顯示在最上面。emmmm,這麼大個問題解決了,偷偷摸個魚不過分吧!愉快的tab切換摸魚模式。可是,什麼鬼!爲啥這個彈窗還跟過來了啊!原來不只是插件頁面置頂了,全部軟件都置頂啊!

正確解決方法如下:

Window window = new Window();
window.Title = "我是WPF彈窗!!!!";
new System.Windows.Interop.WindowInteropHelper(window) { Owner = new IntPtr(Globals.ThisAddIn.Application.HWND) };
window.Show();

在這裏插入圖片描述
這時候就可以看到,焦點在主窗口時,彈窗也不會被遮蓋,並且最小化主窗口的時候,彈窗也會被收起來,切換到別的軟件時,會正常蓋住彈窗!

2、Winform彈窗

Winform的彈窗肯定和WPF的差不多,畢竟也是先有的Winform纔有的WPF。一樣兩句話彈個窗,但是問題也和上面的一樣!

Form form = new Form();
form.Show();

細心一點可以發現,在輸入Show方法的時候,其實是有一個重載方法的,需要傳入一個IWin32Window對象。並且IWin32Window其實是一個接口類,內部只有一個返回句柄的屬性。

//owner:任何實現 System.Windows.Forms.IWin32Window 並表示將擁有此窗體的頂級窗口的對象。
public void Show(IWin32Window owner);

public interface IWin32Window
{
    //獲取表示由實現者的窗口句柄。
    IntPtr Handle { get; }
}

嘗試一下,建一個類繼承IWin32Window接口,然後根據主頁面的句柄去new一下這個類,並作爲參數傳入到Show方法裏面。

public class WinWrap : IWin32Window
{
    private IntPtr m_Handle;
    public IntPtr Handle
    {
        get { return m_Handle; }
    }
    //構造函數,參數是父窗口的句柄
    public WinWrap(int handle)
    {
        this.m_Handle = new IntPtr(handle);
    }
}

Form form = new Form();
form.Text = "這是Winform彈窗!!!";
WinWrap owner = new WinWrap(Globals.ThisAddIn.Application.HWND);
form.Show(owner);

在這裏插入圖片描述

3、Winform彈窗內嵌入WPF控件

由於一些接口只允許傳入Winform窗體或控件,所以需要將WPF控件包裝一下

var toolControl = new Controls.ToolControl();//WPF控件
var form = new System.Windows.Forms.UserControl();//Winform控件
System.Windows.Forms.Integration.ElementHost elementHost = new System.Windows.Forms.Integration.ElementHost();
elementHost.Child = toolControl;
elementHost.Dock = System.Windows.Forms.DockStyle.Fill;
form.Controls.Add(elementHost);      
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章