簡體   English   中英

如何使用KeyPresses在不帶窗口的ElementHost中托管WPF用戶控件

[英]How to host a WPF UserControl in ElementHost without Window with KeyPresses

通過將Child屬性設置為自定義用戶控件,我已經使用ElementHost在Windows應用程序中嵌入了WPF用戶控件。

不幸的是,我的文本框沒有收到來自按鍵的任何輸入,因此我根本無法使用外接程序。

當我發現以下代碼行時,我認為我找到了一種解決方法。

ElementHost.EnableModelessKeyboardInterop([System.Windows.Window]);

由於我沒有使用窗口,因此無法使用。 實際上,無法在元素主機中托管System.Windows.Window或將窗口用作主機。

直到相當多的開發階段,此外接程序才具有任何文本輸入功能,因此一切都陷入了停頓。

如何使輸入內容被文本框接受?

我找到了一個鏈接網上說子clases文本框,並允許擊鍵原職

我稍作更改,但幾乎相同。 它尚未經過全面測試,但按鍵將進入文本框。

class TextInput : TextBox
{
    private const UInt32 DLGC_WANTARROWS = 0x0001;
    private const UInt32 DLGC_WANTTAB = 0x0002;
    private const UInt32 DLGC_WANTALLKEYS = 0x0004;
    private const UInt32 DLGC_HASSETSEL = 0x0008;
    private const UInt32 DLGC_WANTCHARS = 0x0080;
    private const UInt32 WM_GETDLGCODE = 0x0087;
    public TextInput()
    {
        Loaded += delegate
        {
            var s = PresentationSource.FromVisual(this) as HwndSource;
            s?.AddHook(ChildHwndSourceHook);
        };
    }
    static IntPtr ChildHwndSourceHook(IntPtr hwnd, int msg, 
         IntPtr wParam, IntPtr lParam, ref bool handled)
    {
        if (msg != WM_GETDLGCODE) return IntPtr.Zero;
        handled = true;
        return new IntPtr(DLGC_WANTCHARS | DLGC_WANTARROWS | DLGC_HASSETSEL);
    }
}

另一個角度是創建元素宿主的子類並在其中添加代碼。 這樣,如果有其他任何掛鈎自定義設置,則可以在一個位置進行調整,它將級聯到所有wpf控件。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Forms.Integration;
using System.Windows.Interop;
using Automated.ToolWindow;

namespace Automated
{

    public class MyElementHost : ElementHost
    {
        protected override void Dispose(bool disposing)
        {
            if (_contentControl != null)
            {
                _contentControl.Loaded -= OnContentControlOnLoaded;
                _contentControl = null;
            }

            base.Dispose(disposing);
        }

        private ContentControl _contentControl;
        // Hide the child element.
        public new UIElement Child 
        {
            get { return base.Child; }
            set
            {
                _contentControl = new ContentControl();
                _contentControl.Loaded += OnContentControlOnLoaded;
                _contentControl.Content = value;
                base.Child = _contentControl;
            }
        }

        private void OnContentControlOnLoaded(object sender, RoutedEventArgs e)
        {
            var s = PresentationSource.FromVisual(_contentControl) as HwndSource;
            s?.AddHook(ChildHwndSourceHook);
        }

        private const UInt32 DLGC_WANTARROWS = 0x0001;
        private const UInt32 DLGC_WANTTAB = 0x0002;
        private const UInt32 DLGC_WANTALLKEYS = 0x0004;
        private const UInt32 DLGC_HASSETSEL = 0x0008;
        private const UInt32 DLGC_WANTCHARS = 0x0080;
        private const UInt32 WM_GETDLGCODE = 0x0087;

        static IntPtr ChildHwndSourceHook(IntPtr hwnd, 
          int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
        {
            if (msg != WM_GETDLGCODE) return IntPtr.Zero;
            handled = true;
            return new IntPtr(DLGC_WANTCHARS | DLGC_WANTARROWS | DLGC_HASSETSEL);
        }
    }
}

實現后,我添加主機的代碼如下所示。

ElementHost = new MyElementHost()
{ 
    Child =  new RootXamlControl()
};

TaskPanes.Add(_host.TaskPanes.Add((int) ElementHost.Handle, "", 
      TaskPaneCaption, "Auto"));

附帶說明,如果您正在編寫COM加載項而又不關注內存管理,那么對於那些不得不關心垃圾回收的人們來說,您將獲得一種全新的贊賞。 從C#.Net開發人員口語!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM