取消

为什么委托的减法(- 或 -=)可能出现非预期的结果?(Delegate Subtraction Has Unpredictable Result)

当我们为一个委托写 -= 的时候,ReSharper 会提示“Delegate Subtraction Has Unpredictable Result”,即“委托的减法可能出现非预期的结果”。然而在写为事件写 -= 的时候却并没有这样的提示。然而这个提示是什么意思呢?为什么会“非预期”?为什么委托会提示而事件不会提示? 阅读本文将了解委托的减法。 ▲ 委托的减法可能出现非预期的结...

使 32 位程序使用大于 2GB 的内存

不管在 32 位 Windows 上还是在 64 位 Windows 上,32 位的应用程序都只能使用最大 2GB 的内存,这是我们司空见惯的一个设定。但其实 Windows 提供了一些方法让我们打破这样的设定,使程序使用大于 2GB 的内存。 为什么 32 位程序只能使用最大 2GB 内存? 32 位寻址空间只有 4GB 大小,于是 32 位应用程序进程最大只能用到 4GB 的...

让 ScrollViewer 的滚动带上动画

WPF 的 ScrollViewer 没有水平滚动和垂直滚动的属性 HorizontalScrollOffset VerticalScrollOffset,只有水平滚动和垂直滚动的方法 ScrollToHorizontalOffset ScrollToVerticalOffset,那么怎么给滚动过程加上动画呢? 既然没有属性,那我们加个属性好了,反正附加属性就是用来干这个事儿的。 n...

真的要比较 for 和 foreach 的性能吗?(内附性能比较的实测数据)

小伙伴告诉我,List<T>.Find 方法比 List.FirstOrDefault 扩展方法性能更高,详见:C# Find vs FirstOrDefault - 林德熙。这可让我震惊了,因为我从来都没有考虑过在如此微观尺度衡量它们的性能差异。 少不了的源码 于是,我立刻翻开了 Find 和 FirstOrDefault 的源代码: public T Find(...

当我们使用 MVVM 模式时,我们究竟在每一层里做些什么?

这篇文章不会说 MVVM 是什么,因为讲这个的文章太多了;也不会说 MVVM 的好处,因为这样的文章也是一搜一大把。我只是想说说我们究竟应该如何理解 M-V-VM,当我们真正开始写代码时,应该在里面的每一层里写些什么。 MVVM,当然三层——M-V-VM。就凭这个“三层”结构,WPF/UWP 开发者们就能折腾出一个完整的程序出来。M——定义数据模型啊,V——视图啊,VM——视图模型。其...

极限压缩 PNG

为了让博客的访问者有更快的访问速度,同时兼顾显示效果,我们有些选择却不多——比如选用 WebP 格式。但考虑到浏览器兼容性问题,有时不得不考虑依然 PNG。 这里我找到一款极限 PNG 压缩工具——LimitPNG。 limitPNG - PNG 图片极限压缩工具 这是 nullice · 不知语冰 的软件。在极限压缩的时候,压缩一张 PNG 的耗时真的很长,几分钟算是很理想的...

自定义 Windows PowerShell 和 cmd 的字体

Windows 系统下的命令行界面,字体要么是点阵字体,要么是宋体;但无论哪种,始终觉得难看了。然而,字体选择界面却始终没办法选择到我们新安装的各种字体。 本文将推荐一款可以为 PowerShell 和 cmd 使用的等宽字体,适合程序员使用。 对字体要求 当然,安装了 git 后,会自动帮我们安装 mintty,bash 风格,自定义方便,着色也很棒。如果可能,我还是更希望用...

从 Matrix 解构出 Translate/Scale/Rotate(平移/缩放/旋转)

在 XAML 中,我们对一个 UIElement 进行一个 RenderTransform 是再常见不过的事情了,我们可以从众多叠加的 TransformGroup 瞬间得到一个 Matrix 表示整个变换的综合变换矩阵,然而反过来却不好做——从变换矩阵中反向得到变换分量。 首先明确的是,各种 TranslateTransform、ScaleTransform、RotateTransf...

用动画的方式画出任意的路径(直线、曲线、折现)

WPF/UWP 中提供的 Path 类可以为我们绘制几乎所有可能的矢量图形。但是,如果这些矢量图形可以以动画的形式播放出来,那将可以得到非常炫酷的演示效果。 我用 Blend 画了我的名字: <Canvas x:Name="DisplayCanvas" Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2"> <...

使用不安全代码将 Bitmap 位图转为 WPF 的 ImageSource 以获得高性能和持续小的内存占用

在 WPF 中将一个现成的 Bitmap 位图转换成 ImageSource 用于显示一个麻烦的事儿,因为 WPF 并没有提供多少可以转过来的方法。不过产生 Bitmap 来源却非常多,比如屏幕截图、GDI 图、数组或其它非托管框架生成的图片。 WPF 官方提供了一种方法,使用 System.Windows.Interop.Imaging.CreateBitmapSourceFromH...

Visual Studio 也开始支持 Ctrl 点击跳转了,于是需要解决跟 ReSharper 的冲突

微软在 2017年10月9日 发布了 Visual Studio 2017 version 15.4.0。而这个版本带来了大家期待已久的 Ctrl+Click 跳转到定义的功能。然而……ReSharper 也是这样的快捷键,也是这样的功能!!! 居然冲突了啊,怎么办? 这里可以阅读发布日志:Visual Studio 2017 15.4 Release Notes。 Edit...

修复 WPF 窗口在启动期间短暂的白底显示

不管你做的 WPF 窗口做得多么简单,是否总感觉启动的那一瞬间窗口内是白白的一片?是否试过无数偏方黑科技,但始终无法解决? 本文将介绍一种简单的方法来彻底解决这个问题。 看看下面这张图,你便能知道本文要解决的问题是否跟你希望解决的是同一个问题: 是否发现窗口启动期间,窗口中的内容是白色的呢? 然而我的 Window 超级简单: <Window x:Class="Wal...

为 Web 页面添加 iPhone 固定标签页的图标

我曾经将一个 Web 标签页固定到 iPhone 的主屏幕上,发现居然有一个图标。当时没有留意,可直到今天发现我的博客页面在我的 iPhone 主屏幕上显示一片空白后,才想起来原来还可以自定义图标。 将 Web 页面图标固定到主屏幕: 方法非常简单,只需要在我 html 里的 head 中加入以下代码即可: <link rel="apple-touch-icon" hre...

使用 ExceptionDispatchInfo 捕捉并重新抛出异常

当你跑起了一个异步线程,并用 await 异步等待时,有没有好奇为什么能够在主线程 catch 到异步线程的异常? 当你希望在代码中提前收集好异常,最后一并把收集到的异常抛出的时候,能不能做到就像在原始异常发生的地方抛出一样? 本文介绍 ExceptionDispatchInfo,专门用于重新抛出异常。它在 .NET Framework 4.5 中首次引入,并原生在 .NET Core ...

如何组织一个同时面向 UWP/WPF/.Net Core 控制台的 C# 项目解决方案

希望写一个小型工具,给自己和需要的人。考虑到代码尽可能的复用,我准备采用 .Net Standard 来编写大多数核心代码,并基于 .Net Core 编写跨平台控制台入口,用 WPF 编写桌面端 UI 入口,用 UWP 作为可上架商店的 UI 入口,然后用 Shared Project 共享 WPF 和 UI 的多数 UI 入口代码。 阅读本文将了解到如何在尽可能复用代码的情况下组织这样...

UWP 和 WPF 不同,ListView 中绑定的集合修改顺序时,UI 的刷新规则

ObservableCollection<T> 中有一个 Move 方法,而这个方法在其他类型的集合中是很少见的。由于 ObservableCollection<T> 主要用于绑定,涉及到 UI 更新,而 UI 更新普遍比普通的集合修改慢了不止一个数量级,所以可以大胆猜想,Move 的存在是为了提升 UI 刷新性能。 然而事实真是这样的吗? 试验 将 Obs...

GitHub 的 Pull Request 和 GitLab 的 Merge Request 有区别吗?

在 GitHub 上混久了,对 Pull Request 就……;在 GitLab 上混久了,对 Merge Request 就……然而它们之间有不同吗?为什么要用两个不同的名称? 要追溯这两个名称,需要追溯 GitHub 和 GitLab 引以为傲的 git 工作流。这也是本文参考链接中一定要附上 GitLab 工作流的重要原因。 众所周知 git 是一个分布式的版本管理系统,但为...

查询已连接 Wi-Fi 的密码(入门和进阶两种方法)

新买了手机或者带着朋友去好玩的地方,我自己的 Windows 10 设备连接上了 Wi-Fi,朋友也希望连接上,但是我忘记了密码怎么办? 进阶篇 其实重点并不是解决问题,而是解决问题的过程;所以使用命令行来解决这个问题当然更加炫酷一些,当然要第一个讲啦!让其他人投来羡慕的目光吧! 总共两条命令: netsh wlan show profiles 上图是第一条命令执行的...

CaptureMouse/CaptureStylus 可能会失败

在 WPF 中,如果我们要做拖动效果,通常会调用一下 CaptureMouse/CaptureStylus 以便当鼠标或手指离开控件的时候依然能够响应 Move 和 Up 事件。不知有没有注意到这两个函数其实是有 bool 返回值的?——是的,它们可能会失败。 在调试一个项目代码的时候,我就发现了这种失败,观察返回值确实是 false,然而为什么呢? 查看 .NET Framewor...

彻底删除 Git 仓库中的文件避免占用大量磁盘空间

今天早上照常 git fetch --prune 获取大家写的代码,发现需要好长时间,但没怎么在意。直到下午小伙伴们才发现居然 fetch 了一个多 GB!询问才发现小伙伴 JAKE(其实我是在推荐博客)误传了 1.47GB 的垃圾文件。关键是等发现时,develop 分支上已经有 20+ 个基于这个文件的新提交了。 小伙伴说“不要紧,现在我已经删除它了!”突然一阵后背发凉,我们才 900...

使用 PowerShell 获取 CLR 版本号

在我之前写的一篇文章.NET Framework 4.x 程序到底运行在哪个 CLR 版本之上中,我们说到 CLR 版本和 .NET Framework 基础库之间是有差别的,其版本号更是有差别的。不过其中并没有给出方法获取 CLR 的版本号。本文将给出几种方便的获取 CLR 版本号的方法。 写代码获取 .NET Framework 的 System.Environment 类型的 ...

试图在 Windows 10 上安装 .NET Framework 3.5 时提示错误 0x800F081F

说到在 Windows 10 上安装 .NET Framework 3.5,想必已经没什么可以多说的了,直接去“启用或关闭 Windows 功能”界面给“.NET Framework 3.5”打个勾就好了。 但今天帮助一位朋友安装时却在上述步骤之后出现了错误:0x800F081F。 正常安装步骤: 错误: 这不能忍啊!迅速在网上搜索错误码,然而得到的回答要么是换命令行,要...

设置 .NET Native 运行时指令以支持反射(尤其适用于 UWP)

我们经常会尝试用一用反射来解决一部分动态可执行代码的问题,不过这个问题在 UWP 中似乎并不那么轻松。也许你写了一句获取某个类所有属性的代码,结果发现 DEBUG 下跑得好好的,RELEASE 下居然拿不到! 尝试反射获取属性 你的代码可能是这样的: var properties = typeof(SomeType).GetProperties(); 或者这样的: var p...

使用 filter-branch 从 Git 历史中删除一个文件

昨天帮助小伙伴从 Git 提交历史中删除了一个文件,虽然一开始尝试使用 filter-branch,但是因为需要的时间太久,就放弃了,转而使用 cherry-pick 的方案。 但是,毕竟 Git 官方给的方案是 filter-branch,所以今天就在另一位小伙伴的帮助下好好阅读 Git 官方文档:Git - 重写历史 和 Git - git-filter-branch Document...

Why Unload Twice

Sometimes WPF raise unload event twice. In this case, it happens when a logical tree is build all by myself. Why unload twice? It really confused me. Any help would be appreciated! The repo: walte...

找回你 C 盘丢失的空间(SpaceSniffer)

什么鬼!C 盘空间满了!我分了 120GB 啊!!!是不是要删软件删游戏,是不是要重装系统? 尤其是程序员,那么多开发环境(Visual Studio 不说话 :))空间占用那叫一个大啊!为了避免重装系统,我找到了一款神奇的软件——SpaceSniffer。 话不多说,上神器: SpaceSniffer 官网:Uderzo Software SpaceSniffer S...

如何向整个 Git 仓库补提交一个文件

微软在 Reference Source 里开放了 .NET Framework 多个版本的源码。为了更方便地阅读这些源码,我们把每一个版本都下载下来后按顺序提交到 git 仓库中。 但是!!!居然忘了在第一次提交之前放一个 .gitignore 文件!如果没有这个文件,那我们每次打开源码查看都会带来一大堆不明所以的修改文件。那么多的源码,绝对不会想重新挨个版本再提交一次。于是找到了一条可...

Exception.Data 为异常添加更多调试信息

我们抛出异常是为了知道程序中目前的状态发生了错误。为了能够知道错误的详细信息便于我们将来避免产生这样的错误,我们会选用合适的异常类型,在异常中编写易于理解的 message 信息。但是有时我们需要更多的信息进行调试才能帮忙在将来避免这个异常。 System.Exception 类中就自带了这样的属性 Data,它是 IDictionary 类型的: public virtual ID...

WPF 渲染系统(WPF Render System)

一个朋友问我:“为什么几千个 Visual 在视觉树上,增加删除几个能够那么快地渲染出来?”这个问题问倒我了,因为我对 WPF 渲染系统的了解很少,更不知道渲染部分和 UI 逻辑部分是如何分工的。 在此机会下,我毫不犹豫地打开 https://referencesource.microsoft.com/ 阅读 WPF 的源码。 对探索源码章节不感兴趣的读者,可以直接跳到后面大胆猜想与理...

解决XAML设计器中遇到的那些错误

使用 Visual Studio 开发 WPF 程序时,XAML 设计器能够极大提高我们的开发效率。不止是写出的代码无需运行就能看到效果,还有能够直接在设计器中点击定位元素以及拖拽改变属性。 但是,XAML 开发不总是那么幸运! 因为我们总能在设计器中看到这样的一幕: 如果你看完之后无奈又无助,那这篇文章正好将帮你分析 XAML 设计器出错的各种可能原因以及解决这些问题的思路。 ...