【问题标题】:convert wpf textbox to iwin32window (winform)将 wpf 文本框转换为 iwin32window (winform)
【发布时间】:2010-08-19 21:41:48
【问题描述】:

如标题所述,我想将 System.Windows.Controls.Textbox 转换为 IWin32Window。 我读了How to use a FolderBrowserDialog from a WPF application 但它只描述了如何获取winform的句柄,而不是对其进行控制。

谢谢

【问题讨论】:

    标签: wpf winforms


    【解决方案1】:

    WPF 不将 Win32 句柄用于像 TextBox 这样的单个控件,仅用于 Window 本身。换句话说,从 Win32 的角度来看,整个 WPF Window 对象是一个具有单个句柄的单个窗口。

    因此,IWin32Window 返回 WPF 文本框的“实际”Win32 句柄是没有意义的:WPF 文本框根本没有 Win32 句柄。因此,您必须返回某个其他对象的 Win32 句柄。

    如何执行此操作取决于您将使用 IWin32Window 的目的。创建一个 Win32 窗口以对应于您的 TextBox 有多种可能性:

    1. 您可以创建一个与 TextBox 重叠的透明 Win32 窗口(对于命中测试或过度绘制场景很有用)
    2. 您可以创建一个以 TextBox 为中心的零大小窗口(对于对话框初始位置和所有权场景很有用)
    3. 您可以将 TextBox 托管在 ElementHost 而不是 WPF 窗口中(如果您希望 TextBox 适合其他 Win32 内容,例如旧的 MFC 应用程序,这很有用)
    4. 您可以在 WindowsFormsHost 内的 ElementHost 中托管 TextBox(如果您需要围绕 TextBox 的 Win32 窗口但仍需要 WPF 布局,这很有用

    关于“额外窗口”解决方案的说明(1 和 2)

    要创建覆盖 TextBox(透明或零大小)的 Win32 窗口,您可以使用传统的 Win32 或 WinForms 技术。

    由于 TextBox 可以在屏幕上移动,因此您需要在 TextBox 移动时移动 Win32 窗口。这可以在 OnRendering 事件中使用 textBox.TransformToAncestor(window) 完成,然后使用 PresentationSource.TransformToDevice 转换为设备坐标。

    ElementHost 解决方案注意事项(3 和 4)

    这就像在 XAML 中将 ElementHost 包裹在 TextBox 周围一样简单,因此:

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

    可能变成:

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

    这也可以在代码中通过从其父级移除 TextBox,将其添加到新创建的 ElementHost,然后将 ElementHost 添加到新创建的 WindowsFormsHost 并将 WindowsFormsHost 添加回父级来完成。

    请注意,WPF 样式和属性(包括 DataContext、TextElement 属性等)不会通过 ElementHost 向下传播,即使包装在 WindowsFormsHost 中,因此必须手动传播所需的设置和资源。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-29
      • 2011-08-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多