wpf
文章平均质量分 81
walter lv
这个作者很懒,什么都没留下…
展开
-
.NET 程序如何获取图片的宽高(框架自带多种方法的不同性能)
获取图片宽高的方法有很多种,本文介绍 .NET 中获取图片宽高的几种方法并评估其性能。如果你打算对大量图片进行一些处理,本文可能有用。本文内容本文即将评估的方法`System.Drawing.Imaging.Metafile``System.Drawing.Bitmap``System.Windows.Media.Imaging.BitmapImage``System.Windows.Medi...原创 2020-04-30 11:59:43 · 1292 阅读 · 0 评论 -
WPF 中如何创建忽略 DPI 属性的图片
WPF 框架设计为与 DPI 无关,但你依然可能遇到 DPI 问题。尤其是 Image 控件显示的图片会根据图片 EXIF 中的 DPI 信息和屏幕 DPI 自动缩放图片。对于 UI 用图来说这是好事,但对于软件用户随便插入的图片来说就不是了——用户传入的图片可能是各种各样不统一的 DPI。因此这种 DPI 我们应该忽略。本文内容解决方法`DrawingImage`解决方法直接设置 Ima...原创 2020-04-30 11:48:31 · 490 阅读 · 0 评论 -
WPF 中那些可跨线程访问的 DispatcherObject(WPF Free Threaded Dispatcher Object)
众所周知的,WPF 中多数对象都继承自 DispatcherObject,而 DispatcherObject 带给这些对象一个特点:不能跨线程访问。不过,WPF 中依然存在一些例外。本文将介绍 WPF 那些可跨线程访问的 DispatcherObject,如何充分利用这个特点提高应用程序的性能,以及如何自己编写这样的 DispatcherObject。本文内容什么样的 Dispatcher...原创 2020-03-31 07:43:35 · 588 阅读 · 0 评论 -
Windows 10 应用创建模糊背景窗口的三种方法
现代的操作系统中创建一张图片的高斯模糊效果非常容易,不过如果要在窗口中获得模糊支持就需要操作系统的原生支持了。iOS/Mac 和 Windows 系统都对此有支持。本文将介绍三种创建模糊背景窗口的方法。有人可能喜欢称之为毛玻璃窗口、亚克力窗口。This post is written in multiple languages. Please select yours:{% include...原创 2020-02-29 13:38:39 · 1986 阅读 · 0 评论 -
如何编写 WPF 的标记扩展 MarkupExtension,即便在 ControlTemplate/DataTemplate 中也能生效
WPF 的标记扩展为 WPF 带来了强大的扩展性。利用自定义的标记扩展,我们能够为 XAML 中的属性提供各种各样种类的值,而不仅限于自带的那一些。不过有小伙伴发现在 ControlTemplate 或 DataTemplate 中编写标记扩展有时并不能正常工作,而本文将提供解决方法。本文并不会详细讲解如何编写 WPF 的标记扩展,如果你想了解相关的知识,建议阅读官网:Markup Exte...原创 2020-01-28 17:25:35 · 671 阅读 · 0 评论 -
让你编写的控件库在 XAML 中有一个统一的漂亮的命名空间(xmlns)和命名空间前缀
在 WPF XAML 中使用自己定义的控件时,想必大家都能在 XAML 中编写出这个控件的命名空间了。然而——我写不出来,除非借助 ReSharper。如果控件能够有一个漂亮的命名空间和命名空间前缀呢?——好吧,还是写不出来,不过,至少漂亮些。本文将指导你自定义在 XAML 中使用的命名空间。本文内容达到什么样的效果?这是怎么做到的呢?还有什么更高级的玩法吗?一些限制参考资料达到什么样的效...原创 2020-01-28 17:19:20 · 660 阅读 · 2 评论 -
在 WPF 程序中应用 Windows 10 真•亚克力效果
从 Windows 10 (1803) 开始,Win32 应用也可以有 API 来实现原生的亚克力效果了。不过相比于 UWP 来说,可定制性会差很多。本文介绍如何在 WPF 程序中应用 Windows 10 真•亚克力效果。(而不是一些流行的项目里面自己绘制的亚克力效果。)本文内容API如何使用注意事项API需要使用的 API 是微软的文档中并未公开的 SetWindowComposit...原创 2019-12-30 08:48:51 · 3597 阅读 · 0 评论 -
屏幕边缘上有趣的 1 个像素,看不见、摸不到
如果你的屏幕分辨率是 1920×1080,那么一个全屏的窗口程序尺寸是多少呢?想都不用想,是 1920×1080。那么输入设备输入的坐标是多少呢?是 X∈[0, 1919] ?还是 X∈[1, 1920] ?还是 X∈[0, 1920] ?本文内容鼠标输入与触摸输入有趣的 1 像素防踩坑秘籍鼠标输入与触摸输入一个有趣的问题,因为 1920×1080 分辨率的屏幕,其横向只有 1920 个...原创 2019-12-30 08:44:21 · 367 阅读 · 0 评论 -
WPF 高性能位图渲染 WriteableBitmap 及其高性能用法示例
WPF 渲染框架并没有对外提供多少可以完全控制渲染的部分,目前可以做的有:D3DImage,用来承载使用 DirectX 各个版本渲染内容的控件WriteableBitmap,通过一段内存空间来指定如何渲染一个位图的图片HwndHost,通过承载一个子窗口以便能叠加任何种类渲染的控件本文将解释如何最大程度压榨 WriteableBitmap 在 WPF 下的性能。本文内容如何使用 ...原创 2019-12-30 08:04:27 · 8383 阅读 · 0 评论 -
什么是模态窗口?本文带你了解模态窗口的本质
做 Windows 桌面应用开发的小伙伴们对“模态窗口”(Modal Dialog)一定不陌生。如果你希望在模态窗口之上做更多的事情,或者自己实现一套模态窗口类似的机制,那么你可能需要了解模态窗口的本质。本文不会太深,只是从模态窗口一词出发,抵达大家都熟知的一些知识为止。本文内容开发中的模态窗口模态窗口的三个特点实现模态窗口API 调用禁用主窗口阻塞代码等待操作完成进行 UI 强提醒开发中...原创 2019-11-27 08:05:33 · 9451 阅读 · 0 评论 -
直击本质:WPF 框架是如何实现模态窗口的
想知道你在 WPF 编写 Window.ShowDialog() 之后,WPF 框架是如何帮你实现模态窗口的吗?本文就带你来了解这一些。本文内容`Window.ShowDialog``ShowHelper`Window.ShowDialogWPF 显示模态窗口的方法就是 Window.ShowDialog,因此我们直接进入这个方法查看。由于 .NET Core 版本的 WPF 已经开源,...原创 2019-11-27 08:01:45 · 1318 阅读 · 0 评论 -
使用 SetWindowCompositionAttribute 来控制程序的窗口边框和背景(可以做 Acrylic 亚克力效果、模糊效果、主题色效果等)
Windows 系统中有一个没什么文档的 API,SetWindowCompositionAttribute,可以允许应用的开发者将自己窗口中的内容渲染与窗口进行组合。这可以实现很多系统中预设的窗口特效,比如 Windows 7 的毛玻璃特效,Windows 8/10 的前景色特效,Windows 10 的模糊特效,以及 Windows 10 1709 的亚克力(Acrylic)特效。而且这些组合...原创 2019-11-27 07:58:55 · 8475 阅读 · 9 评论 -
WPF 程序如何移动焦点到其他控件
WPF 中可以使用 UIElement.Focus() 将焦点设置到某个特定的控件,也可以使用 TraversalRequest 仅仅移动焦点。本文介绍如何在 WPF 程序中控制控件的焦点。本文内容`UIElement.Focus``TraversalRequest`关于逻辑焦点和键盘焦点跨窗口/跨进程切换焦点UIElement.Focus仅仅需要在任何一个控件上调用 Focus() 方法...原创 2019-11-27 07:50:30 · 2900 阅读 · 0 评论 -
使用 SetParent 制作父子窗口的时候,如何设置子窗口的窗口样式以避免抢走父窗口的焦点
制作传统 Win32 程序以及 Windows Forms 程序的时候,一个用户看起来独立的窗口本就是通过各种父子窗口嵌套完成的,有大量窗口句柄,窗口之间形成父子关系。不过,对于 WPF 程序来说,一个独立的窗口实际上只有一个窗口句柄,窗口内的所有内容都是 WPF 绘制的。如果你不熟悉 Win32 窗口中的父子窗口关系和窗口样式,那么很有可能遇到父子窗口之间“抢夺焦点”的问题,本文介绍如何解决这...原创 2019-11-27 07:49:47 · 2944 阅读 · 0 评论 -
WPF 程序如何跨窗口/跨进程设置控件焦点
WPF 程序提供了 Focus 方法和 TraversalRequest 来在 WPF 焦点范围内转移焦点。但如果 WPF 窗口中嵌入了其他框架的 UI(比如另一个子窗口),那么就需要使用其他的方法来设置焦点了。一个粗略的设置方法是,使用 Win32 API:SetFocus(hwnd);传入的是要设置焦点的窗口的句柄。参考资料winapi - Win32: C++: How d...原创 2019-11-27 07:47:47 · 881 阅读 · 0 评论 -
如何在 WPF 中获取所有已经显式赋过值的依赖项属性
获取 WPF 的依赖项属性的值时,会依照优先级去各个级别获取。这样,无论你什么时候去获取依赖项属性,都至少是有一个有效值的。有什么方法可以获取哪些属性被显式赋值过呢?如果是 CLR 属性,我们可以自己写判断条件,然而依赖项属性没有自己写判断条件的地方。本文介绍如何获取以及显式赋值过的依赖项属性。需要用到 DependencyObject.GetLocalValueEnumerator() 方...原创 2019-11-27 07:44:05 · 465 阅读 · 0 评论 -
在 WPF 中获取一个依赖对象的所有依赖项属性
本文介绍如何在 WPF 中获取一个依赖对象的所有依赖项属性。本文内容通过 WPF 标记获取通过设计器专用方法获取通过 WPF 标记获取public static IEnumerable<DependencyProperty> EnumerateDependencyProperties(object element){ if (element is null) ...原创 2019-11-27 07:43:34 · 622 阅读 · 0 评论 -
WPF 制作高性能的透明背景异形窗口(使用 WindowChrome 而不要使用 AllowsTransparency=True)
在 WPF 中,如果想做一个背景透明的异形窗口,基本上都要设置 WindowStyle="None"、AllowsTransparency="True" 这两个属性。如果不想自定义窗口样式,还需要设置 Background="Transparent"。这样的设置会让窗口变成 Layered Window,WPF 在这种类型窗口上的渲染性能是非常糟糕的。本文介绍如何使用 WindowChrome ...原创 2019-11-27 07:42:44 · 3634 阅读 · 0 评论 -
WPF 不要给 Window 类设置变换矩阵(应用篇)
WPF 的 Window 类是不允许设置变换矩阵的。不过,总会有小伙伴为了能够设置一下试图绕过一些验证机制。不要试图绕过,因为你会遇到更多问题。本文内容试图设置变换矩阵绕过验证小心异常试图设置变换矩阵当你试图给 Window 类设置变换矩阵的时候,会出现异常:System.InvalidOperationException:“转换对于 Window 无效。”无论是缩放还是旋转,都...原创 2019-10-28 09:34:44 · 403 阅读 · 0 评论 -
WPF 不要给 Window 类设置变换矩阵(分析篇):System.InvalidOperationException: 转换不可逆。
最近总是收到一个异常 “System.InvalidOperationException: 转换不可逆。”,然而看其堆栈,一点点自己写的代码都没有。到底哪里除了问题呢?虽然异常堆栈信息里面没有自己编写的代码,但是我们还是找到了问题的原因和解决方法。本文内容异常堆栈分析过程源代码`PointUtil.TryApplyVisualTransform``PointUtil.TryClientToR...原创 2019-10-28 09:33:48 · 705 阅读 · 2 评论 -
WPF 的 Application.Current.Dispatcher 中,Dispatcher 属性一定不会为 null
在 WPF 程序中,可能会存在 Application.Current.Dispatcher.Xxx 这样的代码让一部分逻辑回到主 UI 线程。因为发现在调用这句代码的时候出现了 NullReferenceException,于是就有三位小伙伴告诉我说 Current 和 Dispatcher 属性都可能为 null。然而实际上这里只可能 Current 为 null 而此上下文的 Dispat...原创 2019-10-28 09:27:59 · 3019 阅读 · 0 评论 -
WPF 的 Application.Current.Dispatcher 中,为什么 Current 可能为 null
在 WPF 程序中,可能会存在 Application.Current.Dispatcher.Xxx 这样的代码让一部分逻辑回到主 UI 线程。因为发现在调用这句代码的时候出现了 NullReferenceException,于是就有三位小伙伴告诉我说 Current 和 Dispatcher 属性都可能为 null。然而实际上这里只可能 Current 为 null 而此上下文的 Dispat...原创 2019-10-28 09:00:02 · 2584 阅读 · 0 评论 -
解决 WPF 嵌套的子窗口在改变窗口大小的时候闪烁的问题
因为 Win32 的窗口句柄是可以跨进程传递的,所以可以用来实现跨进程 UI。不过,本文不会谈论跨进程 UI 的具体实现,只会提及其实现中的一个重要缓解,使用子窗口的方式。你有可能在使用子窗口之后,发现拖拽改变窗口大小的时候,子窗口中的内容不断闪烁。如果你也遇到了这样的问题,那么正好可以阅读本文来解决。本文内容问题解决原因问题你可以看一下下面的这张动图,感受一下窗口的闪烁:实际上在拖...原创 2019-10-28 08:58:23 · 2016 阅读 · 2 评论 -
System.ComponentModel.Win32Exception (0x80004005): 无效的窗口句柄。
在 WPF 获取鼠标当前坐标的时候,可能会得到一个异常:System.ComponentModel.Win32Exception:“无效的窗口句柄。”。本文解释此异常的原因和解决方法。异常获取鼠标当前相对于元素 element 的坐标的代码:var point = Mouse.GetPosition(element);或者,还有其他的代码:var point1 = e.PointF...原创 2019-10-28 08:55:42 · 6412 阅读 · 0 评论 -
使用 SetParent 跨进程设置父子窗口时的一些问题(小心卡死)
在微软的官方文档中,说 SetParent 可以在进程内设置,也可以跨进程设置。当使用跨进程设置窗口的父子关系时,你需要注意本文提到的一些问题,避免踩坑。本文内容跨进程设置 `SetParent`消息循环强制同步消息循环强制同步如何解决跨进程设置 SetParent关于 SetParent 函数设置窗口父子关系的文档可以看这个:SetParent function (winuser.h...原创 2019-10-28 08:54:26 · 6137 阅读 · 7 评论 -
System.InvalidOperationException:“寄宿的 HWND 必须是指定父级的子窗口。”
当试图在 WPF 窗口中嵌套显示 Win32 子窗口的时候,你有可能出现错误:“寄宿的 HWND 必须是指定父级的子窗口。”。这是很典型的 Win32 错误,本文介绍如何修复此错误。本文内容问题原因和解决办法我们在 MainWindow 中嵌入一个其他的窗口来承载新的 WPF 控件。一般情况下我们当然不会这么去做,但是如果我们要跨越进程边界来完成 WPF 渲染内容的融合的时候,就需要嵌入一...原创 2019-10-28 08:52:56 · 1629 阅读 · 0 评论 -
System.InvalidOperationException:“BuildWindowCore 无法返回寄宿的子窗口句柄。”
当试图在 WPF 窗口中嵌套显示 Win32 子窗口的时候,你有可能出现错误:“BuildWindowCore 无法返回寄宿的子窗口句柄。”。这是很典型的 Win32 错误,本文介绍如何修复此错误。本文内容问题原因和解决办法我们在 MainWindow 中嵌入一个其他的窗口来承载新的 WPF 控件。一般情况下我们当然不会这么去做,但是如果我们要跨越进程边界来完成 WPF 渲染内容的融合的时...原创 2019-10-19 09:06:42 · 1782 阅读 · 0 评论 -
通过 AppSwitch 禁用 WPF 内置的触摸让 WPF 程序可以处理 Windows 触摸消息
WPF 框架自己实现了一套触摸机制,但同一窗口只能支持一套触摸机制,于是这会禁用系统的触摸消息(WM_TOUCH)。这能够很大程度提升 WPF 程序的触摸响应速度,但是很多时候又会产生一些 Bug。如果你有需要,可以考虑禁用 WPF 的内置的实时触摸(RealTimeStylus)。本文介绍禁用方法,使用 AppSwitch,而不是网上广为流传的反射方法。本文内容如何设置 AppSwitch...原创 2019-10-19 09:00:12 · 1040 阅读 · 0 评论 -
System.InvalidOperationException:“寄宿 HWND 必须是子窗口。”
当试图在 WPF 窗口中嵌套显示 Win32 子窗口的时候,你有可能出现错误:“System.InvalidOperationException:“寄宿 HWND 必须是子窗口。””。这是很典型的 Win32 错误,本文介绍如何修复此错误。本文内容一个最简的嵌入其他窗口的例子寄宿 HWND 必须是子窗口一个最简的嵌入其他窗口的例子我们在 MainWindow 中嵌入一个其他的窗口来承载新...原创 2019-10-19 08:56:54 · 1318 阅读 · 0 评论 -
通过分析 WPF 的渲染脏区优化渲染性能
本文介绍通过发现渲染脏区来提高渲染性能。本文内容脏区 Dirty RegionWPF 性能套件脏区监视优化脏区重绘脏区 Dirty Region在计算机图形渲染中,可以每一帧绘制全部的画面,但这样对计算机的性能要求非常高。脏区(Dirty Region)的引入便是为了降低渲染对计算机性能的要求。每一帧绘制的时候,仅仅绘制改变的部分,在软件中可以节省大量的渲染资源。而每一帧渲染时,改变了需...原创 2019-06-29 09:58:38 · 1831 阅读 · 0 评论 -
WPF 程序鼠标在窗口之外的时候,控件拿到的鼠标位置在哪里?
在 WPF 程序中,我们有 Mouse.GetPosition(IInputElement relativeTo) 方法可以拿到鼠标当前相对于某个 WPF 控件的位置,也可以通过在 MouseMove 事件中通过 e.GetPosition(IInputElement relativeTo) 方法拿到同样的信息。不过,在任意时刻去获取鼠标位置的时候,如果鼠标在窗口之外,将获取到什么点呢?本文将介...原创 2019-06-29 09:56:46 · 2101 阅读 · 0 评论 -
使用 EnumWindows 找到满足你要求的窗口
在 Windows 应用开发中,如果需要操作其他的窗口,那么可以使用 EnumWindows 这个 API 来枚举这些窗口。本文介绍使用 EnumWindows 来枚举并找到自己关心的窗口(如 QQ/TIM 窗口)。本文内容`EnumWindows`遍历所有的顶层窗口遍历具有指定类名或者标题的窗口EnumWindows你可以在微软官网了解到 EnumWindows。要在 C# 代码中使...原创 2019-06-29 09:53:35 · 12648 阅读 · 0 评论 -
WPF 获取元素(Visual)相对于屏幕设备的缩放比例,可用于清晰显示图片
我们知道,在 WPF 中的坐标单位不是屏幕像素单位,所以如果需要知道某个控件的像素尺寸,以便做一些与屏幕像素尺寸相关的操作,就需要经过一些计算(例如得到屏幕的 DPI)。更繁琐的是,我们的控件可能外面有一些其他的控件做了 RenderTransform 进行了一些缩放,于是了解到屏幕像素单位就更不容易了。本文将提供一套计算方法,帮助计算某个 WPF 控件相比于屏幕像素尺寸的缩放比例,用于进行屏...原创 2019-06-29 09:46:35 · 2453 阅读 · 0 评论 -
WPF 像素着色器入门:使用 Shazzam Shader Editor 编写 HLSL 像素着色器代码
HLSL,High Level Shader Language,高级着色器语言,是 Direct3D 着色器模型所必须的语言。WPF 支持 Direct3D 9,也支持使用 HLSL 来编写着色器。你可以使用任何一款编辑器来编写 HLSL,但 Shazzam Shader Editor 则是专门为 WPF 实现像素着色器而设计的一款编辑器,使用它来编写像素着色器,可以省去像素着色器接入到 WPF ...原创 2019-05-26 14:37:46 · 2072 阅读 · 0 评论 -
C# 跨设备前后端开发探索
每个人都拥有 好奇心,好奇心驱使着我们总是去尝试做一些有趣的事情。带起你的好奇心,本文将使用 C# 开发各种各样好玩的东西。[本文内容已加入 2019 年 4 月 13 日的广州 .NET 俱乐部第 2 届线下沙龙。本文内容0x00 序章好奇心先搞起来0x01 C# 跨设备前后端开发Web 后端Windows 桌面端公共代码控制台iOS 端Web 前端0x02 C# 还能做什么?0x0...原创 2019-05-19 17:09:05 · 1240 阅读 · 0 评论 -
将 C++/WinRT 中的线程切换体验带到 C# 中来(WPF 版本)
如果你要在 WPF 程序中使用线程池完成一个特殊的任务,那么使用 .NET 的 API Task.Run 并传入一个 Lambda 表达式可以完成。不过,使用 Lambda 表达式会带来变量捕获的一些问题,比如说你需要区分一个变量作用于是在 Lambda 表达式中,还是当前上下文全局(被 Lambda 表达式捕获到的变量)。然后,在静态分析的时候,也难以知道此 Lambda 表达式在整个方法中的执...原创 2019-05-19 17:01:27 · 1189 阅读 · 0 评论 -
WPF 的命令的自动刷新时机——当你 CanExecute 会返回 true 但命令依旧不可用时可能是这些原因
在 WPF 中,你可以使用 Command="{Binding WalterlvCommand}" 的方式来让 XAML 中的一个按钮或其他控件绑定一个命令。这样,按钮的可用性会自动根据 WalterlvCommand 当前 CanExecute 的状态来改变。这本是一个非常智能的特性,直到你可能发现你按钮的可用性状态不正确……本文介绍默认情况下,WPF 在 UI 上的这些命令会在什么时机进行刷...原创 2019-05-19 17:00:15 · 4261 阅读 · 0 评论 -
WPF 跨应用程序域的 UI(Cross AppDomain UI)
为自己写的程序添加插件真的是一个相当常见的功能,然而如果只是简单加载程序集然后去执行程序集中的代码,会让宿主应用程序暴露在非常危险的境地!因为只要插件能够运行任何一行代码,就能将宿主应用程序修改得天翻地覆哭爹喊娘;而根本原因,就在于暴露了整个托管堆和整个 UI 树。如果将宿主和插件放到不同的应用程序域中,则可以解决此问题。原创 2017-11-23 22:18:20 · 1475 阅读 · 0 评论 -
通过修改环境变量修改当前进程使用的系统 Temp 文件夹的路径
Windows 系统提供了一个在 Windows 单个用户下全局的 Temp 文件夹,用于给各种不同的应用程序提供一个临时目录。但是,直到 Windows 10 推出存储感知功能之前,这个文件夹都一直只归各个应用程序自己管理,应用自己需要删除里面的文件。另外,进程多了,临时文件也会互相影响(例如个数过多、进程读写竞争等等)。本文介绍将自己当前进程的 Temp 文件夹临时修改到应用程序自己的一个临...原创 2019-07-27 20:11:26 · 4987 阅读 · 0 评论 -
WPF 判断一个对象是否是设计时的窗口类型,而不是运行时的窗口
当我们对 Window 类型写一个附加属性的时候,在属性变更通知中我们需要判断依赖对象是否是一个窗口。但是,如果直接判断是否是 Window 类型,那么在设计器中这个属性的设置就会直接出现异常。那么有没有什么方法能够得知这是一个设计时的窗口呢?这样就不会抛出异常,而能够完美支持设计器了。本文内容方法一:判断设计时属性方法二:判断设计时窗口方法一:判断设计时属性WPF 原生自带一个附加属性...原创 2019-07-27 20:12:06 · 730 阅读 · 0 评论