我给博客改了主题色,从 这样的 改成了 这样的;然而我问小伙伴看看效果他却并没有发现改变。 红绿色盲在亚洲人中占比,男性约 5%,女性则小得多。也就是说,就算仅考虑为国内用户开发应用,这也是很大的一部分用户了。 本文将通过更加了解色盲(Color Blindness)来指导我们为更多用户提供更好的 UI 设计。 没有色盲模拟器 大多数想理解色盲眼中世界的人可能会考虑“色盲...
C#/.NET 中的契约式编程,以及 ReSharper 为我们提供的契约特性
将文档放到代码里面,文档才会及时地更新! 微软从 .NET Framework 4.0 开始,增加了 System.Diagnostics.Contracts 命名空间,用来把契约文档融入代码。然而后面一直不冷不热,Visual Studio 都没天然支持。 ReSharper 也提供了 ReSharper Annotations,在 ReSharper 插件工作的情况下能够进行...
我收集的各种公有 NuGet 源
本文收集我发现的各种公共 NuGet 源。 如何添加本文介绍的 NuGet 源? 请参见: 全局或为单独的项目添加自定义的 NuGet 源 官方 NuGet 源 官方源 https://api.nuget.org/v3/index.json 官方离线本地源 C:\Program Files (x8...
在 csproj 文件中使用系统环境变量的值(示例将 dll 生成到 AppData 目录下)
Windows 系统以及很多应用程序会考虑使用系统的环境变量来传递一些公共的参数或者配置。Windows 资源管理器使用 %var% 来使用环境变量,那么我们能否在 Visual Studio 的项目文件中使用环境变量呢? 本文介绍如何在 csproj 文件中使用环境变量。 遇到的问题 在 Windows 资源管理器中,我们可以使用 %AppData% 进入到用户的漫游路径。我...
为 WPF 程序添加 Windows 跳转列表的支持
Windows 跳转列表是自 Windows 7 时代就带来的功能,这一功能是跟随 Windows 7 的任务栏而发布的。当时应用程序要想用上这样的功能需要调用 shell 提供的一些 API。 然而在 WPF 程序中使用 Windows 跳转列表功能非常简单,在 XAML 里面就能完成。本文将介绍如何让你的 WPF 应用支持 Windows 跳转列表功能。 一个简单的跳转列表程...
Windows 上的应用程序在运行期间可以给自己改名(可以做 OTA 自我更新)
程序如何自己更新自己呢?你可能会想到启动一个新的程序或者脚本来更新自己。然而 Windows 操作系统允许一个应用程序在运行期间修改自己的名称甚至移动自己到另一个文件夹中。利用这一点,我们可以很简单直接地做程序的 OTA 自动更新。 本文将介绍示例程序运行期间改名并解释其原理。 在程序运行期间手工改名 我们写一个简单的程序。 将它运行起来,然后删除。我们会发现无法删除它。...
.NET 使用 JustAssembly 比较两个不同版本程序集的 API 变化
最近我大幅度重构了我一个库的项目结构,使之使用最新的项目文件格式(基于 Microsoft.NET.Sdk)并使用 SourceYard 源码包来打包其中的一些公共代码。不过,最终生成了一个新的 dll 之后却心有余悸,不知道我是否删除或者修改了某些 API,是否可能导致我原有库的使用者出现意料之外的兼容性问题。 另外,准备为一个产品级项目更新某个依赖库,但不知道更新此库对我们的影响有多大...
详解 .NET 反射中的 BindingFlags 以及常用的 BindingFlags 使用方式
使用 .NET 的反射 API 时,通常会要求我们传入一个 BindingFlags 参数用于指定反射查找的范围。不过如果对反射不熟的话,第一次写反射很容易写错导致找不到需要的类型成员。 本文介绍 BindingFlags 中的各个枚举标记的含义、用途,以及常用的组合使用方式。 所有的 BindingFlags 默认值 // 默认值 Default 查找 这些标记用于反...
如何使用 MyGet 这个激进的 NuGet 源体验日构建版本的 .NET Standard / .NET Core
很多库都会在 nuget.org 上发布预览版本,不过一般来说这个预览版本也是大多可用的。然而想要体验日构建版本,这个就没有了,毕竟要照顾绝大多数开发者嘛…… 本文介绍如何使用 MyGet 这个激进的 NuGet 源,介绍如何使用框架级别的库的预览版本如 .NET Standard 的预览版本。 加入 MyGet 这个 NuGet 源 添加 NuGet 源的方法在我和林德熙的博...
常用输入法快速输入自定义格式的时间和日期(搜狗/QQ/手心/微软拼音)
几个主流的输入法输入 rq 或者 sj 都可以得到预定义格式的日期或者时间。然而他们都是预定义的格式;当我们需要一些其他格式的时候该怎么做呢? 本文将介绍几个常用输入法自定义时间和日期格式的方法。 主流输入法的日期格式一般是这样的: ▲ 微软拼音 ▲ 搜狗拼音 ▲ QQ 拼音 如果自定义,可以是这样: ▲ UTC 自定义 输出效果像这样: 2018-08-26 ...
使用一句 git 命令将仓库的改动推送到所有的远端
git 支持一个本地仓库包含多个远端(remote),这对于开源社区来说是一个很重要的功能,可以实时获取到最新的开源代码且能推送到自己的仓库中提交 pull request。 有时候多个远端都是自己的,典型的就是 GitHub Pages 服务了,推送总是希望这几个远端能够始终和本地仓库保持一致。本文将介绍一个命令推送到所有远端的方法。 我的博客同时发布在 GitHub 仓库 htt...
.NET/C# 获取一个正在运行的进程的命令行参数
在自己的进程内部,我们可以通过 Main 函数传入的参数,也可以通过 Environment.GetCommandLineArgs 来获取命令行参数。 但是,可以通过什么方式来获取另一个运行着的程序的命令行参数呢? 进程内部获取传入参数的方法,可以参见我的另一篇博客:.NET 命令行参数包含应用程序路径吗?。 .NET Framework / .NET Core 框架内部是不包含获...
WPF 让普通 CLR 属性支持 XAML 绑定(非依赖属性),这样 MarkupExtension 中定义的属性也能使用绑定了
如果你写了一个 MarkupExtension 在 XAML 当中使用,你会发现你在 MarkupExtension 中定时的属性是无法使用 XAML 绑定的,因为 MarkupExtension 不是一个 DependencyObject。 本文将给出解决方案,让你能够在任意的类型中写出支持 XAML 绑定的属性;而不一定要依赖对象(DependencyObject)和依赖属性(Depe...
在 Snoop 中使用 PowerShell 脚本进行更高级的 UI 调试
在 WPF 开发时,有 Snoop 的帮助,UI 的调试将变得非常轻松。使用 Snoop,能轻松地查看 WPF 中控件的可视化树以及每一个 Visual 节点的各种属性,或者查看数据上下文,或者监听查看事件的引发。 不过,更强大的是支持使用 PowerShell 脚本。这使得它即便 UI 没有给你提供一些入口,你也能通过各种方式查看或者修改 UI。 Snoop PowerShel...
四种方法获取可执行程序的文件路径(.NET Core / .NET Framework)
本文介绍四种不同的获取可执行程序文件路径的方法。适用于 .NET Core 以及 .NET Framework。 使用程序集信息获取 var executablePath = Assembly.GetEntryAssembly().Location; 这种方式的思路是获取入口程序集所在的路径。不过 Assembly.GetEntryAssembly() 能获取到的程序集是入口...
UWP 在 WebView 中执行 JavaScript 代码(用于模拟用户输入等)
UWP 中使用 WebView 时可以在网页中额外执行一些代码。于是你几乎可以在网页上做任何事情,那些你可以在浏览器控制台中做的事情。 本文将介绍做法。 准备环境 在页面(XAML)中放一个 WebView,然后取个名字,比如就叫做 WebView。 监听 NavigationCompleted 事件,然后导航到需要操作的页面。 WebView.NavigationComp...
在 Visual Studio Code 中为代码片段(Code Snippets)添加快捷键
Visual Studio Code 默认是关闭了 Markdown 的智能感知提示的(因为真的是不好用,尤其是其没有中文分词的情况下)。那么在没有智能感知提示的情况下如何快速插入代码片段呢? 可以使用快捷键! 本文介绍如何为代码片段绑定快捷键。 代码片段本没有快捷键相关的字段可供设置的,不过在快捷键设置中可以添加代码片段相关的设置。 首先,在 Visual Studio Cod...
WindowsXamlHost:在 WPF 中使用 UWP 控件库中的控件
在 WindowsXamlHost:在 WPF 中使用 UWP 的控件(Windows Community Toolkit) 一文中,我们说到了在 WPF 中引入简单的 UWP 控件以及相关的注意事项。不过,通常更有实际价值的是更复杂的 UWP 控件的引入,通常是一整个 Page。 本文将介绍如何在 WPF 项目中引用 UWP 的控件库。 创建一个 UWP 控件库 建议专门为你...
.NET 中创建支持集合初始化器的类型
对象初始化器和集合初始化器只是语法糖,但是能让你的代码看起来更加清晰。至少能让对象初始化的代码和其他业务执行的代码分开,可读性会好一些。 本文将编写一个类型,可以使用集合初始化器构造这个类型。不只是添加元素的集合初始化器,还有带索引的集合初始化器。 稍微提一下对象初始化器 很普通的类型就可以支持对象初始化器,只需要对象有可以 set 的属性或者可访问的字段即可。 public...
WPF 多线程 UI:设计一个异步加载 UI 的容器
对于 WPF 程序,如果你有某一个 UI 控件非常复杂,很有可能会卡住主 UI,给用户软件很卡的感受。但如果此时能有一个加载动画,那么就不会感受到那么卡顿了。UI 的卡住不同于 IO 操作或者密集的 CPU 计算,WPF 中的 UI 卡顿时,我们几乎没有可以让 UI 响应的方式,因为 WPF 一个窗口只有一个 UI 线程。 No!WPF 一个窗口可以不止一个 UI 线程,本文将设计一个异步...
WindowsXamlHost:在 WPF 中使用 UWP 的控件(Windows Community Toolkit)
Windows Community Toolkit 再次更新到 5.0。以前可以在 WPF 中使用有限的 UWP 控件,而现在有了 WindowsXamlHost,则可以使用更多 UWP 原生控件了。 关于 Windows Community Toolkit 早期版本的 Xaml Bridge,可以参见: WPF 使用 Edge 浏览器 - 林德熙 安装 NuGet 包...
使用并解析 OPML 格式的订阅列表来转移自己的 RSS 订阅(概念篇)
OPML 全称是 Outline Processor Markup Language ,即 大纲处理标记语言。目前流行于收集博客的 RSS 源,便于用户转移自己的订阅项目。 本文将介绍这个古老的格式,并提供一个 .NET 上的简易解析器。 本文分为两个部分,一个是理解 OPML 格式,一个是解析此格式: 概念篇(本文) 解析篇 OPML 格式 RSS 订阅你应该...
使用 Postman 调试 ASP.NET Core 开发的 API
使用 ASP.NET Core 开发简单的后台 API 还是非常容易的。涉及到 GET 请求的调试我们可以用浏览器简单搞定,那么 POST/PUT/DELETE 这样的请求呢? 本文将使用 Postman 来调试这些请求。 简单的 ASP.NET Core 程序 如果你还不清楚如何编写一个 ASP.NET Core 程序,可以阅读 win10 uwp 手把手教你使用 asp d...
项目文件中的已知 NuGet 属性(使用这些属性,创建 NuGet 包就可以不需要 nuspec 文件啦)
知道了 csproj 文件中的一些常用 NuGet 属性,创建 NuGet 包时就可以充分发挥新 Sdk 自动生成 NuGet 包的优势,不需要 nuspec 文件啦。(毕竟 nuspec 文件没有 .csproj 和 .targets 文件强大而又有扩展性。) “项目文件中的已知属性系列”分为两个部分: 项目文件中的已知属性(知道了这些,就不会随便在 csproj 中写死常量...
为什么 C# 的 string.Empty 是一个静态只读字段,而不是一个常量呢?
使用 C# 语言编写字符串常量的时候,你可能会发现可以使用 "" 而不能使用 string.Empty。进一步可以发现 string.Empty 实际上是一个静态只读字段,而不是一个常量。 为什么这个看起来最适合是常量的 string.Empty,竟然使用静态只读字段呢? string.Empty 这个问题,我们需要去看 .NET Core 的源码(当然 .NET Framew...
C#/.NET 调试的时候显示自定义的调试信息(DebuggerDisplay 和 DebuggerTypeProxy)
使用 Visual Studio 调试 .NET 程序的时候,在局部变量窗格或者用鼠标划到变量上就能查看变量的各个字段和属性的值。默认显示的是对象 ToString() 方法调用之后返回的字符串,不过如果 ToString() 已经被占作它用,或者我们只是希望在调试的时候得到我们最希望关心的信息,则需要使用 .NET 中调试器相关的特性。 本文介绍使用 DebuggerDisplayAtt...
透明度叠加算法:如何计算半透明像素叠加到另一个像素上的实际可见像素值(附 WPF 和 HLSL 的实现)
本文介绍透明度叠加算法(Alpha Blending Algorithm),并用 C#/WPF 的代码,以及像素着色器的代码 HLSL 来实现它。 算法 对于算法,我只是搬运工,可以随意搜索到。算法详情请查看:Alpha compositing - Wikipedia。 对于完全不透明的背景和带有透明度的前景,合并算法为: float r = (foreground.r * ...
使用 Xamarin 开发 iOS 键盘扩展(含网络访问)
作为一位 .NET 技术的死忠,开发 iOS 应用当然要使用 Xamarin 啦! 本文用我的阅读的文档和实践为素材,介绍如何使用 Xamarin 开发一个 iOS 的键盘扩展。 你可以在 Walterlv.CloudKeyboard 仓库中获得本文所述的全部源代码。 搭建环境 本文不会花篇幅来讲如何搭建 Xamarin iOS 开发的环境,不然这篇文章就没有重点。 于是,...
如何为你的 Windows 应用程序关联一种或多种文件类型
对于 Windows 桌面应用来说,让应用关联一种或多种文件类型是通过修改注册表来实现的。 本文介绍如何为你的应用关联自定义的文件类型或者关联被广泛使用的文件类型。 文件关联 Windows 上的文件关联是通过文件的扩展名来实现的。有些文件类型是被广泛使用的公共类型,例如 .txt、.png、.mp4 文件;有些则是你自己的应用程序使用的私有类型,例如我自己定义一个 .lvyi...
通过重写预定义的 Target 来扩展 MSBuild / Visual Studio 的编译过程
MSBuild 的编译过程提供了一些可以被重写的 Target,通过重写这些 Target 可以扩展 MSBuild 的编译过程。 重写预定义的 Target 有这些预定义的 Target 可以重写: BeforeCompile, AfterCompile BeforeBuild, AfterBuild BeforeRebuild, AfterRebuild ...