0
votes

As the title describes, I want to convert System.Windows.Controls.Textbox to IWin32Window. I read How to use a FolderBrowserDialog from a WPF application but it only describes how to get handle of winform, not control on it.

Thanks

1

1 Answers

1
votes

WPF does not use Win32 handles for individual controls like TextBox, only for the Window itself. In other words, from Win32's perspective the entire WPF Window object is a single window with single handle.

Because of this, it is meaningless for an IWin32Window to return the "actual" Win32 handle of a WPF TextBox: A WPF TextBox simply doesn't have a Win32 handles. Thus you will have to return a Win32 handle of some other object.

How to do this depends on what you will be using the IWin32Window for. There are several possibilities for creating a Win32 window to correspond to your TextBox:

  1. You could create a transparent Win32 window that overlaps the TextBox (useful for hit-testing or overdrawing scenarios)
  2. You could create a zero-size window that is centered on the TextBox (useful for dialog initial-location and ownership scenarios)
  3. You could host the TextBox in an ElementHost rather than in a WPF Window (useful if you want the TextBox to fit in with other Win32 stuff, such as an old MFC application)
  4. You could host the TextBox in an ElementHost inside a WindowsFormsHost (useful if you need a Win32 window around the TextBox but still need WPF layout

Notes on the "extra window" solutions (1 & 2)

To create a Win32 window that overlays the TextBox (either transparent or zero-size), you would use traditional Win32 or WinForms techniques.

Since the TextBox can move on the screen you would need to move the Win32 window whenever the TextBox moves. This can be done in the OnRendering event using textBox.TransformToAncestor(window) then transforming to device coordinates using PresentationSource.TransformToDevice.

Notes on ElementHost solutions (3 & 4)

This is as simple as wrapping the ElementHost around the TextBox in your XAML, so this:

<Grid>
  ...
  <TextBox ...>
</Grid>

might become:

<Grid>
  ...
  <WindowsFormsHost>
    <ElementHost>
      <TextBox ...>
    </ElementHost>
  </WindowsFormsHost>
</Grid>

This can also be done in code by removing the TextBox from its parent, adding it to a newly-created ElementHost, and then adding the ElementHost to a newly-created WindowsFormsHost and adding the WindowsFormsHost back to the parent.

Note that WPF styles and properties (including DataContext, TextElement properties, etc) do not propagate down through ElementHost, even if wrapped inside a WindowsFormsHost, so the desired settings and resources must be propagated manually.