使用100%缩放比例重新启动Visual Studio 界面模糊的解决方案
问题描述建议:如果是刚开始写WinForm项目 ,建议刚开始就去进行一个替换 ,要不然后面会很麻烦的 ,不仅要计算size 还要去 计算 location 的值
昨天碰到了这个问题 ,当时设置完之后界面就非常的模糊 ,虽然说界面变大了 ,但是看着异常难受 ,很模糊
解决方案
新建应用程序清单文件(Application Manifest File) , 保持默认名称 app.manifest,点击添加。
找到这段代码:
12345<application xmlns="urn:schemas-microsoft-com:asm.v3"> <windowsSettings> <dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware> </windowsSettings></application>
替换DPI相关配置:
1234 ...
未学习WPF缓动路径速率与累加动画学习笔记
面向已经会创建简单动画和关键帧动画,准备继续学习变化节奏、运动轨迹、播放速率与重复累加的读者。推荐环境:.NET 10 LTS + WPF。随附示例使用 net9.0-windows,本文涉及的 API 在 .NET 9 与 .NET 10 中没有变化。最后更新:2026-10-22
目录
缓动关键帧动画的使用
路径动画的使用
动画对象的相关速率
动画对象的执行累加计算
写在前面这份笔记解决什么问题前面的笔记已经完成:
123DoubleAnimationStoryboard线性、离散、样条关键帧
继续做动画时,又会遇到下面这些问题:
123456789起点、终点和时长都一样,为什么有的动画起步慢,有的收尾慢?EasingDoubleKeyFrame 和 EasingFunction 应该怎样选?怎样让一个元素沿曲线移动,而不是只走直线?为什么路径动画需要两条 DoubleAnimationUsingPath?SpeedRatio 和 AccelerationRatio 到底有什么区别?AccelerationRatio 与 DecelerationRatio 相加为什么不能 ...
未学习WPF动画与关键帧学习笔记
面向已经会使用 WPF 基础控件和简单数据绑定,准备系统学习动画、位移、颜色变化与关键帧的读者。推荐环境:.NET 10 LTS + WPF。随附示例使用 net9.0-windows,本文涉及的 API 在 .NET 9 与 .NET 10 中没有变化。最后更新:2026-10-22
目录
简单动画使用小结
位移动画处理
颜色与显示变更动画处理
线性关键帧动画基本使用
离散关键帧动画基本使用
样条关键帧动画基本使用
写在前面这份笔记要解决什么问题上一阶段已经理解了 WPF 动画的基本概念。继续动手时,很快会遇到这些具体问题:
123456789简单动画最少需要写哪几个对象?为什么动画结束后属性会跳回原值?移动控件应该改 Margin、Canvas.Left,还是使用 TranslateTransform?颜色动画为什么有时直接报错?怎样让颜色、透明度和缩放同时变化?多个关键帧怎样写?线性关键帧、离散关键帧、样条关键帧到底有什么区别?为什么关键帧都有 KeyTime,画面看起来却完全不同?动画怎样暂停、继续和重置?
这篇笔记采用“先运行,再拆解”的方式。每一章都包含:
123 ...
未学习WPF自定义路由事件行为与动画学习笔记
面向刚开始学习 WPF、已经会创建窗口和放置按钮,但还不熟悉路由事件、行为封装与动画时间线的读者。推荐环境:.NET 10 LTS + WPF。随附示例使用 net9.0-windows,本文涉及的 API 在 .NET 9 与 .NET 10 中没有变化。最后更新:2026-10-22
目录
自定义路由事件的定义
自定义路由事件执行过程跟踪
行为对象的定义
行为对象的使用
WPF动画与分类
动画的基本定义与使用
写在前面这份笔记要解决什么问题前面的笔记已经讲过 WPF 的基础事件、输入事件、数据绑定和依赖属性。继续往下学习时,很容易遇到下面这些疑问:
123456789普通 C# event 和路由事件到底差在哪里?为什么自定义事件要注册一个 RoutedEvent 标识?一个事件从子元素出发,为什么父元素也能收到?自定义控件怎样把业务消息放进事件参数?行为对象和普通事件处理器有什么区别?为什么行为分离后,按钮还应该继续正常工作?WPF 动画为什么只能作用于依赖属性?Storyboard.Begin 的第二个参数为什么常常要传 true?动画停止后,属性值为什么会回到原来的值 ...
未学习WPF路由拦截键盘拖放与触控学习笔记
面向已经理解 WPF 路由事件基础,准备继续学习「怎样控制事件」「键盘怎样输入」「拖放怎样实现」和「触摸怎样处理」的读者。推荐环境:.NET 10 LTS + WPF。随附示例使用 net9.0-windows,当前电脑可直接编译;这里用到的 API 在 .NET 9 与 .NET 10 中没有变化。最后更新:2026-10-22
目录
路由事件的拦截
路由拦截后的逻辑执行
键盘输入事件
拖拽事件
Touch与多点触控事件
写在前面这份笔记解决什么问题上一篇笔记已经讲过 Preview 隧道、普通事件冒泡和 Handled。真正做界面时,还会遇到下面这些问题:
123456789拦截应该写在 Preview 还是普通事件里?设置 Handled 后,事件到底还在不在?拦截之后还需要做哪些业务动作?KeyDown、TextInput、TextChanged 分别在什么时候发生?为什么 Ctrl+C 有时会被输入框自己处理掉?拖放为什么不是只有一个 Drop 事件?拖到目标上方时,鼠标光标为什么不变成可放下?触摸事件和 Manipulation 事件应该选哪一种?没有触屏的电脑,怎 ...
未学习WPF生命周期输入与路由事件学习笔记
面向刚学完数据绑定,准备理解「程序怎样启动和退出」「事件怎样传递」「拖动和框选怎样实现」的读者。推荐环境:.NET 10 LTS + WPF。随附示例使用 net9.0-windows,当前电脑可直接编译;这里用到的 API 在 .NET 9 与 .NET 10 中没有变化。最后更新:2026-10-21
目录
App生命周期与全局异常捕获
对象事件总结说明
鼠标输入事件
对象拖动案例
框选基本逻辑
路由事件的处理过程
写在前面这份笔记解决什么问题前面的笔记主要在处理「数据怎样显示到界面」。这一篇换一个方向,观察「程序怎样运行」以及「用户操作怎样进入程序」:
12345678WPF 程序启动时,Application 和 Window 谁先谁后?窗口关闭后,程序一定会立刻退出吗?UI 线程、后台线程和 Task 中的异常,能不能只写一个处理器?普通事件、路由事件、生命周期事件有什么区别?鼠标按下时,sender 和 OriginalSource 为什么不是同一个对象?拖动卡片时,为什么卡片会突然跳到鼠标下面?从右下向左上框选时,为什么矩形宽度会变成负数?PreviewMouse ...
WPF多重绑定与应用程序生命周期学习笔记
面向刚学完普通数据绑定,准备理解「多个值怎样合成一个结果」以及「WPF 程序怎样启动和退出」的读者。推荐环境:.NET 10 LTS + WPF。随附示例使用 net9.0-windows,当前电脑可直接编译;这里用到的 API 在 .NET 9 与 .NET 10 中没有变化。最后更新:2026-10-20
目录
多重绑定基本使用
多重值转换器
优先级绑定
绑定关系清除
应用启动事件与启动参数
应用退出事件
写在前面这份笔记解决什么问题前面的笔记已经讲过一条绑定怎样把一个来源值送到一个目标属性。真正写界面时,经常还会遇到下面这些情况:
123456姓、名、职位分别存在三个属性里,界面要合成一句话。单价、数量、折扣共同决定应付金额,不能只绑定其中一个。主价格没有时用缓存价,缓存价没有时用默认价,再没有就显示“暂无报价”。某条绑定暂时不想用了,怎样停掉?以后还能恢复吗?程序启动时怎样接收命令行参数?窗口关闭和应用退出有什么区别?退出码在哪里读?
本篇分成两个部分。第 1 到第 3 章处理多个值怎样合成一个结果;第 4 章讲绑定关系的清除与恢复;第 5、6 章把绑定放进整个 WP ...
WPF数据验证与错误提示学习笔记
面向已经会写绑定、写过转换器的读者,这一篇把「输入错了怎么办」这件事从头讲清楚。推荐环境:.NET 10 LTS + WPF。随附示例使用 net9.0-windows,以便在已安装 .NET 9 SDK 的电脑上直接编译;用到的验证机制在 .NET 9 和 .NET 10 中没有变化。最后更新:2026-10-20
目录
基于 IDataErrorInfo 的数据验证
IDataErrorInfo 中的属性判断
结合特性的属性验证过程
基于正则表达式的数据验证
结合异常信息提示的输入框模板
写在前面这份笔记解决什么问题上一篇笔记讲的是转换器和 ValidationRule,重点在「怎么把值翻译过去」和「怎么拦住不合法的值」。这一篇换个角度,专门讲数据对象自己怎么报告错误,以及界面怎么把这些错误显示出来。
具体回答六个问题:
123456模型实现 IDataErrorInfo 之后,WPF 到底在什么时候调用它?索引器里的 columnName 是什么?为什么有时校验根本不触发?属性上写 [Required]、[Range] 这些特性,WPF 会自动认吗?正则校验为什么容易「看 ...
WPF转换器与数据校验学习笔记
面向已经练过绑定基础、准备把「数据和界面之间的翻译」这件事做扎实的读者。推荐环境:.NET 10 LTS + WPF。随附示例使用 net9.0-windows,以便在当前安装了 .NET 9 SDK 的电脑上直接编译。这里用到的转换与校验机制在 .NET 9 和 .NET 10 中没有变化。最后更新:2026-10-20
目录
系统默认 ValueConverter
ConverterParameter 的使用
基于 Converter 的性别绑定案例
FallbackValue 与 TargetNullValue 属性
绑定数据异常与捕获
自定义 ValidationRule
写在前面这份笔记解决什么问题前一篇笔记讲的是绑定的五个可配置项,其中已经用过 Converter。但那时的重点是「转换器放在链路的什么位置」,这一篇要往下走一层,回答几个更具体的问题:
123456不写转换器的时候,界面到底是怎么把 1234.5 变成文字的?所有类型都能变吗?ConverterParameter 传进来是什么类型?为什么我传了数字却当成字符串用了?两个单选按钮怎么绑同一个「性别」字段 ...
学习中WPF绑定细节与常见问题学习笔记
面向已经练过数据绑定和数据源,准备把绑定写稳、写准、写顺的读者。推荐环境:.NET 10 LTS + WPF。随附示例使用 net9.0-windows,以便在当前安装了 .NET 9 SDK 的电脑上直接编译。这里用到的绑定机制在 .NET 9 和 .NET 10 中没有变化。最后更新:2026-10-20
目录
绑定常见问题处理:相对源与多级联动问题
绑定对象的 Mode 属性
绑定对象的 UpdateSourceTrigger 与 Delay 属性
绑定对象的 StringFormat 属性
绑定对象的 Converter 属性
写在前面这份笔记解决什么问题前面几篇笔记把绑定的主干讲完了:值和界面怎么连、来源从哪里来、模板怎么用、列表怎么呈现。到这一步,大部分界面都能写出来了。
但真正开始写业务界面以后,问题往往不是「绑不上」,而是「绑上了但不对劲」:
12345模板里想用外面的数据,路径写对了却一直空白,为什么?同一个属性,有时候界面改不动来源,有时候又改得动,差别在哪?文本框每敲一个字就触发一次查询,太频繁了,能不能等一下再触发?金额显示成 1234.5,想要 $1, ...
WPF列表控件与集合呈现学习笔记
面向已经练过依赖属性、数据绑定和数据模板,准备系统学习列表控件与集合呈现的读者。推荐环境:.NET 10 LTS + WPF。随附示例使用 net9.0-windows,以便在当前安装了 .NET 9 SDK 的电脑上直接编译。这里用到的列表控件、模板和绑定机制在 .NET 9 和 .NET 10 中没有变化。最后更新:2026-10-19
目录
列表控件的子项结构区别
集合子项模板与数据模板的组合使用
数据集合的不同呈现方式
ComboBox 的绑定使用
多级数据联动案例
写在前面这份笔记解决什么问题前面五篇笔记走完了一条从属性到界面的路:
笔记
回答的问题
WPF 依赖属性学习笔记
属性怎样参与 WPF 的值系统
WPF 依赖属性进阶笔记
元数据、属性值继承和附加属性
WPF 数据绑定学习笔记
绑定怎样把值和界面连起来
WPF 绑定数据源学习笔记
绑定表达式里的来源对象从哪里来
WPF 数据模板与集合绑定学习笔记
一份数据怎样用不同外观呈现
到这里,你已经能让数据显示出来了。可一旦动手写真正的业务界面,问题马上变成另一批:
12345同样是显 ...
WPF数据模板与集合绑定学习笔记
面向已经完成基础数据绑定练习,准备学习尺寸均分、多区域联动、集合呈现和数据模板的读者。推荐环境:.NET 10 LTS + WPF。随附示例使用 net9.0-windows,以便在当前安装了 .NET 9 SDK 的电脑上直接编译。这里用到的布局、绑定和模板机制在 .NET 9 和 .NET 10 中没有变化。最后更新:2026-10-19
目录
基于界面控件绑定的尺寸均分处理
多区域整合绑定的数据关系
集合数据类型的绑定与数据呈现
数据模板触发器
数据模板选择器
基于数据集合绑定的直方图案例
写在前面这份笔记解决什么问题前面四篇笔记走完了一条完整的路:
笔记
回答的问题
WPF 依赖属性学习笔记
属性怎样参与 WPF 的值系统
WPF 依赖属性进阶笔记
元数据、属性值继承和附加属性
WPF 数据绑定学习笔记
绑定怎样把值和界面连起来
WPF 绑定数据源学习笔记
绑定表达式里的来源对象从哪里来
到这里,语法已经够用了,但真正动手写界面时还会遇到新的问题:
1234三列宽度怎样自动均分,不用手算?左边选了部门,中间和右边怎样自动跟着变?一个集合,怎样 ...
WPF绑定数据源学习笔记
面向已经完成基础数据绑定练习,准备继续学习数据源提供器、XML、DataContext 和 RelativeSource 的读者。推荐环境:.NET 10 LTS + WPF。随附示例使用 net9.0-windows,以便在当前安装了 .NET 9 SDK 的电脑上直接编译。这里用到的绑定机制在 .NET 9 和 .NET 10 中没有变化。最后更新:2026-10-19
目录
基于对象方法的数据源使用
基于 XML 数据的数据源使用
DataContext 数据源使用
RelativeSource 数据源使用
RelativeSource 对象参数说明
写在前面这份笔记解决什么问题前一篇《WPF 数据绑定学习笔记》回答的是“绑定怎样把值和界面连起来”。这一篇继续回答一个更具体的问题:
1绑定表达式里的来源对象,到底从哪里来?
同样一句:
1<TextBlock Text="{Binding Name}" />
在不同位置可能从 DataContext 取数据,也可能从资源里的方法返回值、XML 节点或某个祖先控件取数据 ...
学习中WPF数据绑定学习笔记
面向已经了解 WPF 基本控件和依赖属性,准备系统学习数据绑定的读者。推荐环境:.NET 10 LTS + WPF。随附示例使用 net9.0-windows,以便在当前安装了 .NET 9 SDK 的电脑上直接编译。数据绑定机制在 .NET 9 和 .NET 10 中没有变化。最后更新:2026-10-19
目录
数据绑定的基本关系
基于依赖对象的数据绑定
基于普通数据类型的数据绑定
基于对象的数据绑定
基于ADO.NET的数据绑定
基于Linq的数据绑定
写在前面这份笔记怎么用这份笔记有三种阅读方式:
路线
做法
适合情况
直接运行
打开随附示例,逐个切换六个页签
想先看到效果
逐步跟做
从第 1 章开始,在同一个 WPF 项目中添加代码
想亲手敲一遍
按需查阅
直接阅读对应来源类型的章节
已经遇到具体绑定问题
建议至少完成第 1 章,因为后面的所有示例都建立在同一套绑定语法上。
示例项目位置1C:\Users\North\Desktop\WPF学习笔记\示例代码\WpfDataBindingDemo
运行方式:
123cd "C:\Us ...
已学习WPF依赖属性学习笔记
面向刚开始学习 WPF 的读者。推荐环境:.NET 10 LTS + WPF。示例项目为了能在当前只安装了 .NET 9 SDK 的机器上直接编译,目标框架写成了 net9.0-windows。依赖属性的写法在 .NET 9 和 .NET 10 中没有变化,把目标框架改一行即可。最后更新:2026-10-19
目录
依赖属性的声明
依赖属性的注册
依赖属性的值变化回调
依赖属性的值验证回调
依赖属性的值强置回调
自定义容器的依赖属性改造
写在前面这份笔记怎么用这份笔记有两种用法,可以任选一种:
路线
做法
适合情况
跟做路线
新建一个 WPF 项目,从第 1 章开始逐步加入代码
想亲手敲一遍
对照路线
直接打开随附示例,运行后对照章节阅读
想先看到效果
无论选择哪条路线,都建议按照下面的顺序操作:
先运行程序,观察界面变化。
再看调试输出,确认回调确实被调用了。
最后回到代码,理解每个参数和回调的职责。
示例项目位置:
1C:\Users\North\Desktop\WPF学习笔记\示例代码\WpfDependencyPropertyDemo
示例项目 ...
WPF依赖属性进阶笔记
WPF 依赖属性进阶学习笔记
面向已经写过一两个依赖属性,准备继续学习元数据、继承和附加属性的读者。推荐环境:.NET 10 LTS + WPF。随附示例使用 net9.0-windows,以便在当前安装了 .NET 9 SDK 的电脑上直接编译。依赖属性机制在 .NET 9 和 .NET 10 中没有变化。最后更新:2026-10-19
目录
依赖属性的元数据选项
依赖属性的继承
依赖附加属性的定义
依赖附加属性的应用
写在前面这份笔记和上一篇的关系上一篇《WPF 依赖属性学习笔记》解决的是“怎样把一个普通属性改造成依赖属性”:
1声明 -> 注册 -> 变化回调 -> 验证回调 -> 强制回调
这一篇继续向前一步,解决的是“依赖属性怎样和 WPF 的其他机制配合”:
本篇主题
回答的问题
元数据选项
属性变化后,WPF 应该自动做什么
属性值继承
值怎样从祖先元素流向子孙元素
附加属性定义
怎样给“别人的元素”增加一个属性
附加属性应用
附加属性怎样在 XAML、C# 和容器布局中工作
如果上一篇还没有读过,建议先完成其中 ...
CSharp中的ref和out关键字使用
ref 是双向传递,out 是只出不进。
ref 和 out 都是用在方法参数上的关键字,用来改变「参数传递」的方式。之前你在 TryParse 里已经见过 out 了,这篇把 ref 和 out 一起讲清楚。
一、先搞清楚:默认是「复制一份」方法参数默认按值传递,等于复制一份。
先看一段代码,理解默认行为:
12345678910111213141516using System;class Program{ static void Main() { int x = 10; Change(x); // 把 x 传进去 Console.WriteLine(x); // 还是 10,没变! } static void Change(int n) { n = 999; // 改的是 n,不是 x }}
运行结果是 10,不是 999。因为传参时,只是把 x ...
CSharp字符串与数值类型相互转换
字符串和数字互相转换,上位机几乎天天要用。
为什么需要互转?因为两边的「身份」不一样。
界面输入框里,用户敲进 25.6,程序拿到的是字符串 string,不是数字,没法直接做加减乘除。
PLC 通过 Modbus 传来的温度是数字,但显示到屏幕上、写进日志里,又得变成字符串。
所以必须学会两个方向:数字变字符串、字符串变数字。
本篇目标:会用 ToString 把数字变字符串,会用 Parse、TryParse 把字符串变数字,知道字符串转数字最大的坑,能用 TryParse 写出不崩溃的代码。
一、数值转字符串(简单方向)数字变字符串很简单,两个办法。
办法一:用加号拼接1234567891011121314151617using System;class Program{ static void Main() { double temp = 25.6; int count = 100; // 数字和字符串用 + 连,数字自动变成字符串 string s1 = " ...

















