![](/img/trans.png)
[英]How to get a reference to the Window from a WPF UserControl hosted in a WinForms ElementHost
[英]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.