Ask a questionAsk a question
 

AnswerWindows Form opening WPF window

  • Thursday, January 11, 2007 11:40 AMLuke R Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

    I have a Windows Form project containing a Windows Form that opens a blank WPF window with a TextBox control and the text is not displaying within the TextBox with keyboard input.

    If I copy the XAML to a WPF .NET 3.0 project the text will be displayed within the TextBox. However within my normal VB.NET Windows Form project the TextBox is not displaying the key presses when the WPF window is opened from a Windows Form.  Does something need to be added to the project to ensure that the WPF controls will work fine when opened from a Windows Form?

    XAML code is as follows:

    <Window x:Class="Window1"
    xmlns=http://schemas.microsoft.com/winfx/2006/xaml/presentation
    xmlns:x=http://schemas.microsoft.com/winfx/2006/xaml
    Title="Window" Height="512" Width="727">
    <Grid>
    <FlowDocumentScrollViewer Margin="20,60,20,98" Name="FlowDocumentScrollViewer" />
    <TextBox Height="61" Margin="23,0,117,21" Name="TextBox" VerticalAlignment="Bottom" TextWrapping="Wrap" FlowDirection="LeftToRight" RenderOptions.BitmapScalingMode="Unspecified"></TextBox>
    </Grid>
    </Window>

    Also, I did some testing and checking the KeyDown event does output the keys that are pressed.  Simply the key is not being displayed within the WPF window / textBox.

    Even when creating a WPF project and adding a Windows Form to that project the issue will still occur.  The only way to not have the issue to occur is to use a WPF form and load the WPF window using the App.xaml file.  Is there a workaround for this so that a Windows Form can be loaded and then WPF windows can be loaded from that Windows Form window.

    It seems that when this is done the events are not working properly within the WPF window.  Any ideas?

Answers

  • Thursday, January 11, 2007 7:06 PMChango V. - MSFT Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Answer

    Proper input interop with a non-WPF host (such as WinForms) requires some cooperation between the host and the WPF input system. The topic Sharing Message Loops Between Win32 and WPF  in the SDK explains this well. At a minimum, you have to call ComponentDispatcher.RaiseThreadMessage() from the host’s message loop. In your setup, the easiest way to make this happen is to use code like this:

       Window w = new Window1();

       System.Windows.Forms.Integration.ElementHost.EnableModelessKeyboardInterop(w);

       w.Show();

     

    ElementHost.EnableModelessKeyboardInterop() essentially registers an input hook with the WinForms Application object (which normally runs the message loop) and calls ComponentDispatcher.RaiseThreadMessage().

All Replies

  • Thursday, January 11, 2007 7:06 PMChango V. - MSFT Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Answer

    Proper input interop with a non-WPF host (such as WinForms) requires some cooperation between the host and the WPF input system. The topic Sharing Message Loops Between Win32 and WPF  in the SDK explains this well. At a minimum, you have to call ComponentDispatcher.RaiseThreadMessage() from the host’s message loop. In your setup, the easiest way to make this happen is to use code like this:

       Window w = new Window1();

       System.Windows.Forms.Integration.ElementHost.EnableModelessKeyboardInterop(w);

       w.Show();

     

    ElementHost.EnableModelessKeyboardInterop() essentially registers an input hook with the WinForms Application object (which normally runs the message loop) and calls ComponentDispatcher.RaiseThreadMessage().

  • Friday, January 12, 2007 12:41 PMZhou Yong Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Proposed Answer
    This can also do the trick:
    Window wnd = new Window();
    wnd.Show();
    System.Windows.Threading.Dispatcher.Run();

    Sheva

  • Friday, January 12, 2007 6:06 PMChango V. - MSFT Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    For a hybrid application, this is not a correct solution in general. Running the WPF message loop alone (which the Dispatcher does) can deprive WinForms of some of the messages it needs. In particular, tabbing within a winform/window is likely to be broken.
  • Friday, January 12, 2007 7:57 PMZhou Yong Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    You are right, Chango, and also if you open the WPF window as a modal dialog, the problem disappears, I believe the nested message pump will internally call the ComponentDispatcher.RaiseThreadMessage() method.

    Sheva
  • Thursday, January 10, 2008 5:35 PMSwindler Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    How would you do this when embedding a WPF UserControl inside a Windows Form? The EnableModelessKeyboardInterop function only takes a Window (not a UserControl) and according to my limited knowledge of WPF you can't embed a WPF Window inside a Windows Form.

    Any ideas?
  • Thursday, January 10, 2008 7:52 PMChango V. - MSFT Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Use the ElementHost class to host WPF controls, preferably UserControl-based, in WinForms.
  • Thursday, January 10, 2008 8:33 PMSwindler Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Right, I've already got my WPF UserControl-derived object inside an ElementHost which is inside a Form. The problem is getting keyboard input to my object. I can't seem to use ElementHost.EnableModelessKeyboardInterop(Window) because it takes a Window, not a UserControl. How do you get around this?
  • Thursday, January 10, 2008 10:38 PMChango V. - MSFT Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    In this setup, ElementHost should be doing the input delegation/handling for the hosted WPF control. If you let WinForms run the message loop normally, you shouldn't have to do anything special. Please describe more about the structure of your application and what specific problem you are having. It may be good to start a new thread, since this one was originally about top-level windows, and the issues are somewhat different.
  • Thursday, January 10, 2008 11:30 PMSwindler Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Ok, I created a new thread here: http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2664391&SiteID=1