杭州哪家公司做网站好,微信商店怎么开通,seo一个月赚多少钱,建设企业银行网站WPF Hwnd窗口互操作系列
第一章 嵌入Hwnd窗口 第二章 嵌入WinForm控件 第三章 嵌入WPF控件#xff08;本章#xff09; 文章目录 WPF Hwnd窗口互操作系列前言一、如何实现#xff1f;1、继承HwndHost2、添加Content属性3、创建wpf窗口并设置Content4、关闭wpf窗口 二、完整…WPF Hwnd窗口互操作系列
第一章 嵌入Hwnd窗口 第二章 嵌入WinForm控件 第三章 嵌入WPF控件本章 文章目录 WPF Hwnd窗口互操作系列前言一、如何实现1、继承HwndHost2、添加Content属性3、创建wpf窗口并设置Content4、关闭wpf窗口 二、完整代码三、使用示例1、嵌入控件2、嵌入Window1xaml中定义Window2嵌入已有的Window 3、显示在WinForm控件上面 总结 前言
通过前面的章节我们了解到了如何嵌入Hwnd窗口以及WinForm控件但是嵌入的控件存在覆盖wpf控件的情况嵌入控件上面无法显示王鹏飞控件对UI的布局有一定的影响。本文提供一种解决方法 将wpf控件通过HwndHost的方式嵌入到wpf界面中以实现HwndHost控件上显示wpf控件的功能。 一、如何实现
1、继承HwndHost
和其他嵌入方式一样需要先继承HwndHost。
public class WpfElementHost : HwndHost2、添加Content属性
添加一个Content属性提供给xaml使用。这个Content属性就是需要嵌入的wpf控件。
[ContentProperty(Content)]
public class WpfElementHost : HwndHost
{public UIElement Content{get { return (UIElement)GetValue(ContentProperty); }set { SetValue(ContentProperty, value); }}public static readonly DependencyProperty ContentProperty DependencyProperty.RegisterAttached(Content, typeof(UIElement), typeof(WpfElementHost), new PropertyMetadata(null));
}3、创建wpf窗口并设置Content
实现抽象方法窗口wpf窗口这里参考第一章的嵌入wpf窗口以及给窗口设置Content属性。
protected override HandleRef BuildWindowCore(HandleRef hwndParent)
{var window Content is Window ? Content as Window : new Window { WindowStyle WindowStyle.None, ResizeMode ResizeMode.NoResize, Focusable false, Width 0, Height 0, ShowInTaskbar false, ShowActivated false, Background Brushes.Transparent, Content Content, AllowsTransparency true };var hwnd new WindowInteropHelper(window).EnsureHandle();SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) | WS_CHILD);User32.SetParent(hwnd, hwndParent.Handle);window!.Show();return new HandleRef(this, hwnd);
}4、关闭wpf窗口
实现抽象方法关闭窗口
protected override void DestroyWindowCore(HandleRef hwnd)
{var window HwndSource.FromHwnd(hwnd.Handle)?.RootVisual as Window;window?.Close();
}二、完整代码
WpfElementHost.cs
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Interop;
using System.Windows.Markup;
using Brushes System.Windows.Media.Brushes;
namespace WpfHwndElement
{[ContentProperty(Content)]public class WpfElementHost : HwndHost{public UIElement Content{get { return (UIElement)GetValue(ContentProperty); }set { SetValue(ContentProperty, value); }}public static readonly DependencyProperty ContentProperty DependencyProperty.RegisterAttached(Content, typeof(UIElement), typeof(WpfElementHost), new PropertyMetadata(null));const int GWL_STYLE (-16);const int WS_CHILD 0x40000000;[DllImport(user32.dll, EntryPoint GetWindowLongW)]static extern int GetWindowLong(IntPtr hwnd, int nIndex);[DllImport(user32.dll, EntryPoint SetWindowLongW)]static extern int SetWindowLong(IntPtr hwnd, int nIndex, int dwNewLong);[DllImport(user32.dll)]public static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);protected override HandleRef BuildWindowCore(HandleRef hwndParent){var window Content is Window ? Content as Window : new Window { WindowStyle WindowStyle.None, ResizeMode ResizeMode.NoResize, Focusable false, Width 0, Height 0, ShowInTaskbar false, ShowActivated false, Background Brushes.Transparent, Content Content, AllowsTransparency true };var hwnd new WindowInteropHelper(window).EnsureHandle();SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) | WS_CHILD);SetParent(hwnd, hwndParent.Handle);window!.Show();return new HandleRef(this, hwnd);}protected override void DestroyWindowCore(HandleRef hwnd){var window HwndSource.FromHwnd(hwnd.Handle)?.RootVisual as Window;window?.Close();}}
}三、使用示例
1、嵌入控件
Window x:ClassWpfApp6.MainWindowxmlnshttp://schemas.microsoft.com/winfx/2006/xaml/presentationxmlns:xhttp://schemas.microsoft.com/winfx/2006/xamlxmlns:dhttp://schemas.microsoft.com/expression/blend/2008xmlns:mchttp://schemas.openxmlformats.org/markup-compatibility/2006xmlns:localclr-namespace:WpfApp6mc:IgnorabledTitleMainWindow Height360 Width640Gridlocal:WpfElementHost Width400 Height200TextBox BackgroundRoyalBlue ForegroundWhite FontSize24 /TextBox/local:WpfElementHost/Grid
/Window效果预览
2、嵌入Window
1xaml中定义Window
因为默认嵌入控件的承载Window使用了AllowsTransparency如果需要自己定制窗口属性则可以直接使用Window
Window x:ClassWpfApp6.MainWindowxmlnshttp://schemas.microsoft.com/winfx/2006/xaml/presentationxmlns:xhttp://schemas.microsoft.com/winfx/2006/xamlxmlns:dhttp://schemas.microsoft.com/expression/blend/2008xmlns:mchttp://schemas.openxmlformats.org/markup-compatibility/2006xmlns:localclr-namespace:WpfApp6mc:IgnorabledTitleMainWindow Height360 Width640Gridlocal:WpfElementHost Width400 Height200Window TitleWPF窗口TextBox BackgroundRoyalBlue ForegroundWhite FontSize24 /TextBox/Window/local:WpfElementHost/Grid
/Window效果预览
2嵌入已有的Window
创建一个新的Window1
Window x:ClassWpfApp6.MainWindowxmlnshttp://schemas.microsoft.com/winfx/2006/xaml/presentationxmlns:xhttp://schemas.microsoft.com/winfx/2006/xamlxmlns:dhttp://schemas.microsoft.com/expression/blend/2008xmlns:mchttp://schemas.openxmlformats.org/markup-compatibility/2006xmlns:localclr-namespace:WpfApp6mc:IgnorabledTitleMainWindow Height360 Width640Gridlocal:WpfElementHost Width400 Height200local:Window1 /local:Window1/local:WpfElementHost/Grid
/Window效果预览
3、显示在WinForm控件上面
Window x:ClassWpfApp6.MainWindowxmlnshttp://schemas.microsoft.com/winfx/2006/xaml/presentationxmlns:xhttp://schemas.microsoft.com/winfx/2006/xamlxmlns:dhttp://schemas.microsoft.com/expression/blend/2008xmlns:mchttp://schemas.openxmlformats.org/markup-compatibility/2006xmlns:localclr-namespace:WpfApp6xmlns:wfclr-namespace:System.Windows.Forms;assemblySystem.Windows.Formsmc:IgnorabledTitleMainWindow Height450 Width800GridWindowsFormsHost Width300 Height80 wf:TextBox TextWinForm TextBox BackColor255,192,192,192 //WindowsFormsHostlocal:WpfElementHost Width200 Height100TextBox Opacity0.6 BackgroundRoyalBlue ForegroundWhite FontSize24 TextWPF TextBox /TextBox/local:WpfElementHost/Grid
/Window
效果预览 总结
以上就是今天要讲的内容整体的代码实现是比较简单的关键是在win32 api设置窗口属性。这个功能的作用还是不小的比如在嵌入网页上显示wpf控件或者hwnd播放控件上放一些按钮。这种实现方式也不会有性能问题绘制都是以窗口为单位的其实和WinForm有点类似了每个控件都是一个窗口。