WPF مربع نص لا يقبل الإدخال عندما تكون في ElementHost في نافذة الأشكال

StackOverflow https://stackoverflow.com/questions/835878

سؤال

ونحن نعمل على تطوير واجهة المستخدم التحكم في WPF إلى أن تستهلك في غضون القائمة Windows Forms / MFC التطبيق المحرك (Rhino 3D).

تطبيق محرك يعرض على إنشاء "Dockbar" الذي يتيح لك أساسا وضع نماذج Windows الضوابط داخل نافذة الطفل الذي يمكن أن ترسو على محركات واجهة.

أنا محاولة لوضع بسيطة WPF مربع نص داخل ElementHost السيطرة ، الذي يضاف إلى Dockbar.ويبدو أن تعمل بشكل جيد للوهلة الأولى;ولكن بعد محاولة اكتب في مربع النص فقط تسلسل معين في الواقع تظهر في مربع النص.على حذف, BACKSPACE, نسخ, لصق, ، اختيار النص العمل.إذا كنت من النوع A-Z, 1-9, الخ.هذه المفاتيح لا تظهر.

جبت النت, و قد سمعت عن ElementHost.EnableModelessKeyboardInterop() ولكن هذا ينطبق فقط على WPF ويندوز يجري إنشاؤها من النموذج.أنا فقط خلق WPF UserControls واستضافة لهم في ElementHost التحكم.

رأيت وظيفة التي تحدثت عن المرسل.تشغيل () ، و هذا النوع من الأعمال ولكن يكسر ما تبقى من شكل:

System.Windows.Threading.Dispatcher.Run();

على PreviewKeyUp, PreviewKeyDown, KeyUp, ، KeyDown الأحداث كل النار على مربع النص, ولكن للأسف لا يوجد نص يظهر في مربع النص.

أنا لا أعرف الكثير عن ويندوز الرسائل ، ولكن باستخدام WinSpector لاحظت أن لا WM_GETTEXT الرسائل القادمة من مربع النص (إذا كان ينبغي أن يكون أنا لا أعرف).

أنا أيضا إنشاء نماذج Windows المشروع و فعلت نفس الشيء هناك و أنه يعمل بشكل جيد ، لذلك يجب أن يكون مشكلة مع كيفية التشغيل windows إنشاء رست داخل Rhino 3D المحرك.

هنا هو نموذج التعليمات البرمجية التي لا تعمل:

ElementHost el = new ElementHost();
System.Windows.Controls.TextBox t = new System.Windows.Controls.TextBox();
t.Width = 100;
t.Text = "TEST";
el.Child = t;
panel1.Controls.Add(el);
هل كانت مفيدة؟

المحلول

وأخيرا اكتشفت ذلك بعد 2 أيام من رئيس scatching...

MFC نافذة الحوار كان يأخذ WM_CHAR رسائل ومنع سيطرة من التعامل مع المدخلات.وذلك من أجل منع هذا ، لقد ربط HwndSource و كلما أتلقى WM_GETDLGCODE رسالة أرد مرة أخرى مع أنواع المدخلات لقبول ثم علامة الحدث التعامل معها.

أنا خلقت بلدي مربع نص في للحيلولة دون الحاجة إلى إصلاح كل مربع نص (انظر أدناه):

    /// <summary>
    /// Interop Enabled TextBox : This TextBox will properly handle WM_GETDLGCODE Messages allowing Key Input
    /// </summary>
    class IOTextBox : 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 IOTextBox() : base()
        {
            Loaded += delegate
                          {
                              HwndSource s = HwndSource.FromVisual(this) as HwndSource;
                              if (s != null)
                                  s.AddHook(new HwndSourceHook(ChildHwndSourceHook));
                          };
        }

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

نصائح أخرى

تحقق من بلدي سؤال حول هذا نفس الشيء.في النهاية على الرغم من كل ما تحتاجه هو شيء من هذا القبيل:

Window window1 = new Window();
ElementHost.EnableModelessKeyboardInterop(window1);
window1.Show();

لماذا هو بلدي WPF مربع نص "كيندا" للقراءة فقط?

لدي مشكلة مشابهة مع wxWidgets الإطار الأصل جزءا لا يتجزأ من WPF تحكم مربع نص.لقد وجدت أنه على الرغم من أن ربط ChildHwndSourceHook هل حل مشكلة عدم تلقي مدخلات لوحة المفاتيح ، انتهى مع عرضية مكررة الفضاء الشخصيات.يبدو WM_KEYDOWN رسالة يتعامل مع الفضاء شخصيات موثوق بها ، ولكن مكررة WM_CHAR الرسالة كما وردت عن بعض المساحات.لحل هذه انا إضافة البند التالي إلى الجسم من ChildHwndSourceHook وظيفة ، والتي ببساطة يتجاهل WM_CHAR المساحة الشخصية:

        const UInt32 WM_CHAR = 0x0102;

        if (msg == WM_CHAR)
        {
            // avoid duplicated spaces when parent window is a native window
            if (wParam.ToInt32() == 32)
                handled = true;
        }

فإنه ليس من الضروري إنشاء المستمدة من النص.رمز IOTextBox يمكن استخدامها في UserControl استضافة مربعات النص.لقد اختبرت بنجاح مع WPF التحكم المستخدمة في خيارات مخصصة الصفحة المستخدمة في VS2010 الحزمة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top