当前位置: 首页 > news >正文

C# wpf 嵌入wpf控件

WPF Hwnd窗口互操作系列

第一章 嵌入Hwnd窗口
第二章 嵌入WinForm控件
第三章 嵌入WPF控件(本章)
第四章 底部嵌入HwndHost


文章目录

  • WPF Hwnd窗口互操作系列
  • 前言
  • 一、如何实现?
    • 1、继承HwndHost
    • 2、添加Content属性
    • 3、创建wpf窗口并设置Content
    • 4、关闭wpf窗口
  • 二、完整代码
  • 三、使用示例
    • 1、嵌入控件
    • 2、嵌入Window
      • (1)xaml中定义Window
      • (2)嵌入已有的Window
    • 3、显示在WinForm控件上面
  • 总结


前言

通过前面的章节我们了解到了如何嵌入Hwnd窗口以及WinForm控件,但是嵌入的控件存在覆盖wpf控件的情况,嵌入控件上面无法显示王鹏飞控件,对UI的布局有一定的影响。本文提供一种解决方法,
将wpf控件通过HwndHost的方式嵌入到wpf界面中,以实现HwndHost控件上显示wpf控件的功能。


一、如何实现?

1、继承HwndHost

和其他嵌入方式一样,需要先继承HwndHost。

public class WpfElementHost : HwndHost

2、添加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:Class="WpfApp6.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"xmlns:local="clr-namespace:WpfApp6"mc:Ignorable="d"Title="MainWindow" Height="360" Width="640"><Grid><local:WpfElementHost Width="400" Height="200"><TextBox Background="RoyalBlue" Foreground="White" FontSize="24" ></TextBox></local:WpfElementHost></Grid>
</Window>

效果预览
在这里插入图片描述

2、嵌入Window

(1)xaml中定义Window

因为默认嵌入控件的承载Window使用了AllowsTransparency,如果需要自己定制窗口属性则可以直接使用Window

<Window x:Class="WpfApp6.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"xmlns:local="clr-namespace:WpfApp6"mc:Ignorable="d"Title="MainWindow" Height="360" Width="640"><Grid><local:WpfElementHost Width="400" Height="200"><Window Title="WPF窗口"><TextBox Background="RoyalBlue" Foreground="White" FontSize="24" ></TextBox></Window></local:WpfElementHost></Grid>
</Window>

效果预览
在这里插入图片描述

(2)嵌入已有的Window

创建一个新的Window1
在这里插入图片描述

<Window x:Class="WpfApp6.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"xmlns:local="clr-namespace:WpfApp6"mc:Ignorable="d"Title="MainWindow" Height="360" Width="640"><Grid><local:WpfElementHost Width="400" Height="200"><local:Window1 ></local:Window1></local:WpfElementHost></Grid>
</Window>

效果预览
在这里插入图片描述

3、显示在WinForm控件上面

<Window x:Class="WpfApp6.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"xmlns:local="clr-namespace:WpfApp6"xmlns:wf="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"mc:Ignorable="d"Title="MainWindow" Height="450" Width="800"><Grid><WindowsFormsHost Width="300" Height="80" ><wf:TextBox  Text="WinForm TextBox" BackColor="255,192,192,192" /></WindowsFormsHost><local:WpfElementHost Width="200" Height="100"><TextBox Opacity="0.6" Background="RoyalBlue" Foreground="White" FontSize="24" Text="WPF TextBox" ></TextBox></local:WpfElementHost></Grid>
</Window>

效果预览
在这里插入图片描述


总结

以上就是今天要讲的内容,整体的代码实现是比较简单的,关键是在win32 api设置窗口属性。这个功能的作用还是不小的,比如在嵌入网页上显示wpf控件,或者hwnd播放控件上放一些按钮。这种实现方式也不会有性能问题,绘制都是以窗口为单位的,其实和WinForm有点类似了,每个控件都是一个窗口。

相关文章:

C# wpf 嵌入wpf控件

WPF Hwnd窗口互操作系列 第一章 嵌入Hwnd窗口 第二章 嵌入WinForm控件 第三章 嵌入WPF控件&#xff08;本章&#xff09; 第四章 底部嵌入HwndHost 文章目录 WPF Hwnd窗口互操作系列前言一、如何实现&#xff1f;1、继承HwndHost2、添加Content属性3、创建wpf窗口并设置Conten…...

云原生(六)、CICD - Jenkins快速入门

Jenkuns快速入门 一、CICD概述 CICD是持续集成&#xff08;Continuous Integration&#xff09;和持续部署&#xff08;Continuous Deployment&#xff09;的缩写。它是软件开发中的一种流程和方法论&#xff0c;旨在通过自动化的方式频繁地将代码集成到共享存储库中&#xf…...

基于java+springboot+vue实现的付费自习室管理系统(文末源码+Lw+ppt)23-400

摘 要 付费自习室管理系统采用B/S架构&#xff0c;数据库是MySQL。网站的搭建与开发采用了先进的java进行编写&#xff0c;使用了springboot框架。该系统从两个对象&#xff1a;由管理员和用户来对系统进行设计构建。主要功能包括&#xff1a;个人信息修改&#xff0c;对用户…...

【JavaParser笔记02】JavaParser解析Java源代码中的类字段信息(javadoc注释、字段​​​​​​​名称)

这篇文章,主要介绍如何使用JavaParser解析Java源代码中的类字段信息(javadoc注释、字段名称)。 目录 一、JavaParser依赖库 1.1、引入依赖 1.2、获取类成员信息 (1)案例代码 <...

Spring IoCDI(3)

DI详解 接下来学习一下依赖注入DI的细节. 依赖注入是一个过程, 是指IoC容器在创建Bean时, 去提供运行时所依赖的资源, 而资源指的就是对象. 在之前的案例中, 使用了Autowired这个注解, 完成了依赖注入这个操作. 简单来说, 就是把对象取出来放到某个类的属性中. 在一些文章中…...

保研线性代数机器学习基础复习1

1.什么是代数&#xff08;algebra&#xff09;? 为了形式化一个概念&#xff0c;构建出有关这个概念的符号以及操作符号的公式。 2.什么是线性代数&#xff08;linear algebra&#xff09;&#xff1f; 一项关于向量以及操作向量的公式的研究。 3.举一些向量的例子&#x…...

js绑定事件的方法

在JavaScript中&#xff0c;绑定事件的方法主要有以下几种&#xff1a; HTML属性方式&#xff1a;直接在HTML元素中使用事件属性来绑定事件。 html<button onclick"alert(Hello World!)">Click Me</button> DOM属性方式&#xff1a;通过JavaScript代码…...

是德科技keysight N9000B 信号分析仪

181/2461/8938产品概述&#xff1a; 工程的内涵就是将各种创意有机地联系起来&#xff0c;并解决遇到的问题。 CXA 信号分析仪具有出色的实际性能&#xff0c;它是一款出类拔萃、经济高效的基本信号表征工具。 它的功能十分强大&#xff0c;为一般用途和教育行业的用户执行测试…...

软考 - 系统架构设计师 - 架构风格

软件架构风格是指描述特定软件系统组织方式的惯用模式。组织方式描述了系统的组成构件&#xff0c;以及这些构件的组织方式&#xff0c;惯用模式指众多系统所共有的结构和语义。 目录 架构风格 数据流风格 批处理架构风格 管道 - 过滤器架构风格 调用 / 返回风格 主程序…...

CleanMyMac X2024专业免费的国产Mac笔记本清理软件

非常高兴有机会向大家介绍CleanMyMac X 2024这款专业的Mac清理软件。它以其强大的清理能力、系统优化效果、出色的用户体验以及高度的安全性&#xff0c;在Mac清理软件市场中独树一帜。 CleanMyMac X2024全新版下载如下: https://wm.makeding.com/iclk/?zoneid49983 一、主要…...

ES6 模块化操作

ES6模块化主要有两个操作&#xff1a;import 和 export 如果在html文件的script中引用模块的话&#xff0c;要设置<script type"module"> 一种导入导出方法&#xff1a; a.js//分别暴露 export let num 1 export function compute(a, b){return a b }//统…...

统计XML文件内标签的种类和其数量及将xml格式转换为yolov5所需的txt格式

1、统计XML文件内标签的种类和其数量 对于自己标注的数据集&#xff0c;需在标注完成后需要对标注好的XML文件校验&#xff0c;下面是代码&#xff0c;只需将SrcDir换成需要统计的xml的文件夹即可。 import os from tqdm import tqdm import xml.dom.minidomdef ReadXml(File…...

《操作系统导论》第14章读书笔记:插叙:内存操作API

《操作系统导论》第14章读书笔记&#xff1a;插叙&#xff1a;内存操作API —— 杭州 2024-03-30 夜 文章目录 《操作系统导论》第14章读书笔记&#xff1a;插叙&#xff1a;内存操作API1.内存类型1.1.栈内存&#xff1a;它的申请和释放操作是编译器来隐式管理的&#xff0c;所…...

HAProxy + Vitess负载均衡

一、环境搭建 Vitess环境搭建&#xff1a; 具体vitess安装不再赘述&#xff0c;主要是需要启动3个vtgate&#xff08;官方推荐vtgate和vtablet数量一致&#xff09; 操作&#xff1a; 在vitess/examples/common/scripts目录中&#xff0c;修改vtgate-up.sh文件&#xff0c;…...

2024年京东云主机租用价格_京东云服务器优惠价格表

2024年京东云服务器优惠价格表&#xff0c;轻量云主机优惠价格5.8元1个月、轻量云主机2C2G3M价格50元一年、196元三年&#xff0c;2C4G5M轻量云主机165元一年&#xff0c;4核8G5M云主机880元一年&#xff0c;游戏联机服务器4C16G配置26元1个月、4C32G价格65元1个月、8核32G费用…...

qt-C++笔记之QSpinBox控件

qt-C笔记之QSpinBox控件 code review! 文章目录 qt-C笔记之QSpinBox控件1.运行2.main.cpp3.main.pro4.《Qt6 C开发指南》&#xff1a;4.4 QSpinBox 和QDoubleSpinBox 1.运行 2.main.cpp #include <QApplication> #include <QSpinBox> #include <QPushButton&g…...

Linux(CentOS)/Windows-C++ 云备份项目(服务器网络通信模块,业务处理模块设计,断点续传设计)

此模块将网络通信模块和业务处理模块进行了合并 网络通信通过httplib库搭建完成业务处理&#xff1a; 文件上传请求&#xff1a;备份客户端上传的文件&#xff0c;响应上传成功客户端列表请求&#xff1a;客户端请求备份文件的请求页面&#xff0c;服务器响应文件下载请求&…...

【QQ版】QQ群短剧机器人源码 全网短剧机器人插件

内容目录 一、详细介绍二、效果展示2.效果图展示 三、学习资料下载 一、详细介绍 QQ版本可以兼容两个框架&#xff08;HTQQ&#xff0c;MYQQ这两个的vip版也可以使用) 支持私聊与群聊&#xff0c;命令是 搜剧影视关键词 如果无法搜索到影视资源&#xff0c;请使用下方命令&…...

矩阵间关系的建立

参考文献 2-D Compressive Sensing-Based Visually Secure Multilevel Image Encryption Scheme 加密整体流程如下: 我们关注左上角这一部分: 如何在两个图像之间构建关系,当然是借助第3个矩阵。 A. Establish Relationships Between Different Images 简单说明如下: …...

【C++】C到C++的入门知识

目录 1、C关键字 2、命名空间 2.1 命名空间的定义 2.2 命名空间的使用 2.2.1 加命名空间名称及作用域限定符 2.2.2 使用using将命名空间中某个成员引入 2.2.3 使用using namespace 命名空间名称引入 3、C输入&输出 4、缺省参数 4.1 缺省参数的概念 4.2 缺省参数的…...

【c++】简单的日期计算器

&#x1f525;个人主页&#xff1a;Quitecoder &#x1f525;专栏&#xff1a;c笔记仓 朋友们大家好啊&#xff0c;在我们学习了默认成员函数后&#xff0c;我们本节内容来完成知识的实践&#xff0c;来实现一个简易的日期计算器 目录 头文件声明函数函数的实现1.全缺省默认构…...

基于easyx库的C/C++游戏编程实例-飞机大战

飞机大战游戏设计 首先创建飞机/子弹结构&#xff1a; struct Plane {int x;int y;bool live;int width;int height;int type;int hp; }player,bul[BUL_NUM],enemy[ENE_NUM];你需要加载图片&#xff1a; void ImageLoad() {//背景loadimage(&bg[0], "./image/飞机大…...

stitcher类实现多图自动拼接

效果展示 第一组&#xff1a; 第二组&#xff1a; 第三组&#xff1a; 第四组&#xff1a; 运行代码 import os import sys import cv2 import numpy as npdef Stitch(imgs,savePath): stitcher cv2.Stitcher.create(cv2.Stitcher_PANORAMA)(result, pano) stitcher.st…...

Ubuntu下udp通信

一、知识准备阶段 socket是什么&#xff1f;套接字是什么&#xff1f; https://blog.csdn.net/m0_37925202/article/details/80286946 Socket程序从Windows移植到Linux下的一些注意事项 sockaddr和sockaddr_in详解 bzero和memset函数 函数原型&#xff1a;void bzero&…...

拌合楼管理软件开发(十三) 对接耀华XK3190-A9地磅(实战篇)

前言: 实战开整 目前而言对于整个拌合楼管理软件开发,因为公司对这个项目还处于讨论中,包括个人对其中的商业逻辑也存在一些质疑,都是在做一些技术上的储备.很早就写好了串口与地磅对接获取代码,也大概知道真个逻辑,这次刚好跟库区沟通,远程连接到磅房电脑,开始实操一下. 一、地…...

FastAPI+React全栈开发10 MongoDB聚合查询

Chapter02 Setting Up the Document Store with MongoDB 10 Aggregation framework FastAPIReact全栈开发10 MongoDB聚合查询 In the following pages, we will try to provide a brief introducton to the MongoDB aggregation framework, what it is, what benefits it of…...

python 报错问题汇总

error: [WinError 32] 另一个程序正在使用此文件&#xff0c;进程无法访问。: d:\\anaconda\\envs\\yolov5\\lib\\site-packages\\ISR-2.2.0-py3.7.egg 解决方法&#xff1a;重启pycharm python-contrib 无法安装 opencv-contrib-python 安装包网址&#xff1a;安装包下载链接…...

6.5物联网RK3399项目开发实录-驱动开发之LCD显示屏使用(wulianjishu666)

90款行业常用传感器单片机程序及资料【stm32,stc89c52,arduino适用】 链接&#xff1a;https://pan.baidu.com/s/1M3u8lcznKuXfN8NRoLYtTA?pwdc53f LCD使用 简介 AIO-3399J开发板外置了两个LCD屏接口&#xff0c;一个是EDP&#xff0c;一个是LVDS&#xff0c;接口对应板…...

「Android高级工程师」BAT大厂面试基础题集合-下-Github标星6-5K

C、 com.android.provider.contact D、 com.android.provider.contacts 11.下面关于ContentProvider描述错误的是&#xff08;&#xff09;。 A、 ContentProvider可以暴露数据 B、 ContentProvider用于实现跨程序共享数据 C、 ContentProvider不是四大组件 D、 ContentP…...

【算法】基数排序

简介 基数排序&#xff08;*Radix sort&#xff09;是一种非比较排序算法&#xff08;non-comparative sorting algorithm&#xff09;。现代计算机的基数排序算法由 计数排序 算法的开发人哈罗德H西华德&#xff08;Harold H. Seward&#xff09;于1954年于麻省理工大学开发。…...

a做爰视频免费观费网站/网站流量排名查询工具

企业使用终端可以很好的为企业节省IT费用&#xff0c;具体如下&#xff1a; 一、为企业节省IT费用节省IT费用包括&#xff1a;*节省购买费用*节省用电费用*节省升级费用以下我们分析如何节省费用*节省购买费用举例&#xff1a;企业需要购买30台电脑给文员使用&#xff0c;我们使…...

张家界seo网站优化/自己建网站

运算符1.算数运算 运算符 描述 实例 a10&#xff0c;b20 加&#xff0c;两个对象相加 ab输出30 - 减&#xff0c;一个数减去另一个数 a-b输出-10 * 乘&#xff0c;两个数相乘或是返回一个被重复若干次的字符串 a*b输出200 / 除&am…...

网上做衣服的网站有哪些/seo博客网站

要解决JSP乱码,首先就要了解JSP乱码的原因1.架设服务器安装MYSQL时的会让你选择一种编码,如果这种编码与你的网页不一致,可能就会造成JSP页面乱码2.在PHPMYADMIN或mysql-front等系统 创建数据库时会让你选择一种编码,如果这种编码与你的网页不一致,也有可能造成JSP页面乱码3.创…...

武汉哪家网站建设公司好/最近重大新闻

题目链接地址&#xff1a; http://ac.jobdu.com/problem.php?pid1389 题目1389&#xff1a;变态跳台阶 时间限制&#xff1a;1 秒内存限制&#xff1a;32 兆特殊判题&#xff1a;否提交&#xff1a;2331解决&#xff1a;1332 题目描述&#xff1a; 一只青蛙一次可以跳上1…...

重庆网站建设解决方案/网络优化的三个方法

我的新书《Android App开发入门与实战》已于2020年8月由人民邮电出版社出版&#xff0c;欢迎购买。点击进入详情 文章目录如果你最近在使用git命令&#xff0c;你会发现输入github的账号密码会报错。比如&#xff1a;git push origin master当你输入github的帐号密码后&#xf…...

桂林象鼻山门票/深圳优化公司哪家好

“Gotham” by James Gilleard♚作者&#xff1a;Nugine专栏地址&#xff1a;zhuanlan.zhihu.com/c_168195059在本篇文章中&#xff0c;我要向你展示使用 Cython 扩展 Python 的技巧。如果你同时有 C/C和 Python 的编码能力&#xff0c;我相信你会喜欢这个的。我们要造的轮子是…...