HandyControl 在 .NET 9 / VS2022 下编译报错修复操作记录
> 源码路径:`D:\HandyControl\HandyControl-master`
> 控件库版本:3.6.0.0
> 操作日期:2026-09-14
> 目标:在只安装了 .NET SDK 9(无 .NET 10)、Visual Studio 2022 17.12 的环境下,让 WPF 演示程序 `HandyControlDemo_Net_GE45` 正常编译运行,消除 VS 中的报错。
1. 问题现象
即使在 Visual Studio 顶部把目标框架勾选为 `net9.0-windows`,生成时仍出现三类报错:
- .NET 10 / VS 版本不支持:
-
`当前 Visual Studio 版本不支持面向 .NET 10.0。请面向 .NET 9.0 或更低版本,或者使用 Visual Studio 17.16 或更高版本`
-
`项目 HandyControl 与 net9.0 不兼容。项目 HandyControl 支持: net10.0`
-
`项目"..\HandyControl_Avalonia\HandyControl_Avalonia.csproj"指向"net10.0",不能被指向 net9 的项目引用`
- 大量 XAML 命名空间错误(每个页面刷一片):
-
`XML 命名空间"https://handyorg.github.io/handycontrol"中不存在标记"TransitioningContentControl / SimplePanel / Window / BlurWindow / EnumDataProvider ..."`
-
`...中不存在属性"IconElement.Geometry / InfoElement.Placeholder / Dialog.Token ..."`
- 错误数量看似成百上千,无从逐条修改。
2. 根因分析
2.1 真正的病根:工程里仍然包含本机不支持的 .NET 10 目标
-
WPF 三个工程都是**多目标工程**(`TargetFrameworks` 为复数列表),列表末尾都带有 `net10.0-windows`:
-
`src\Net_GE45\HandyControl_Net_GE45\HandyControl_Net_GE45.csproj`
-
`src\Net_GE45\HandyControlDemo_Net_GE45\HandyControlDemo_Net_GE45.csproj`
-
`src\Shared\HandyControlDemo_Code\HandyControlDemo_Code.csproj`(Demo 引用的共享代码工程,最容易被漏掉)
-
Avalonia 两个工程被**写死**为单一 .NET 10 目标:`src\Avalonia\Directory.Build.props` 中 `<TargetFramework>net10.0</TargetFramework>`。
-
本机环境:.NET SDK 仅 **9.0.102**(无 .NET 10 SDK/Targeting Pack);Visual Studio 为 **17.12**,.NET 10 需要 **17.16+**。
2.2 为什么"勾选了 net9.0-windows"没有用
Visual Studio 工具栏的目标框架下拉,只决定"按 F5 调试/运行时使用哪一个目标框架(TFM)",**并不会从工程文件中删除其它目标框架**。当执行"生成/重新生成解决方案"、或 XAML 设计器做设计时检查时,MSBuild 仍会遍历解决方案内每个工程的**全部**目标框架,于是照样去编译 `net10.0-windows` 以及写死 net10 的 Avalonia 工程,从而报错。多目标工程之间做项目引用兼容性判断时,还会出现"引用方是 net9、被引用方当前解析到 net10 → 不兼容"。
2.3 海量 XAML"命名空间不存在标记"是派生错误,不是独立问题
因为 HandyControl 程序集在 net10 目标上构建失败、XAML 编译器无法加载 `hc:`(`xmlns:hc="https://handyorg.github.io/handycontrol"`)命名空间下的任何类型,才导致所有用到 HandyControl 控件的页面集体报"不存在标记/属性"。**根因(net10)一旦消除,这些错误会成片自动消失,无需逐条处理。**
3. 已执行的修改清单
3.1 修改 3 个 WPF 工程文件,移除 net10 目标
对以下 3 个 `.csproj`,把 `TargetFrameworks` 列表末尾的 `;net10.0-windows` 删除(保留其余所有目标框架,属最小、可逆改动):
| 文件 | 修改前(结尾片段) | 修改后(结尾片段) |
|---|---|---|
| `src\Net_GE45\HandyControl_Net_GE45\HandyControl_Net_GE45.csproj` | `...;net8.0-windows;net9.0-windows;net10.0-windows` | `...;net8.0-windows;net9.0-windows` |
| `src\Net_GE45\HandyControlDemo_Net_GE45\HandyControlDemo_Net_GE45.csproj` | 同上 | 同上 |
| `src\Shared\HandyControlDemo_Code\HandyControlDemo_Code.csproj` | 同上 | 同上 |
> 说明:未把目标框架改成只留 net9,而是仅删除本机无法编译的 net10,这样将来安装 .NET 10 后仍可按需加回,且不影响对 net45~net9 等其它框架的支持。
3.2 清理编译中断残留的临时工程文件
删除了 4 个 WPF 编译过程中残留在 `src\Net_GE45\HandyControl_Net_GE45\` 目录下的临时文件(它们内部仍记录旧的 net10 目标,正常重新生成时会自动重建):
-
`HandyControl_Net_GE45_54ihb20x_wpftmp.csproj`
-
`HandyControl_Net_GE45_bj30g0zx_wpftmp.csproj`
-
`HandyControl_Net_GE45_borr0dsx_wpftmp.csproj`
-
`HandyControl_Net_GE45_oqjg1ic3_wpftmp.csproj`
3.3 未改动的部分
-
**未修改** `src\Avalonia\Directory.Build.props`(仍为 net10.0)。原因:Avalonia 演示线还依赖 `Microsoft.EntityFrameworkCore.SqlServer 10.0.12`、Avalonia 11.3.6 等包,直接降级 TFM 可能引入新的还原问题;而当前只需要 WPF 版本,因此采用"在 VS 中卸载 Avalonia 工程"的方式规避(见第 4 节)。
-
未修改任何业务源码、XAML 与共享工程内容。
4. 在 Visual Studio 中需要配合执行的步骤
工程文件已在磁盘上改好,VS 侧按以下步骤刷新:
-
**重新加载工程**:VS 顶部弹出"文件已在外部被修改"时点"全部重新加载";若未弹出,直接关闭 VS 后重新打开 `src\HandyControl.sln`。
-
**卸载用不到的工程**(在"解决方案资源管理器"中右键工程 →"卸载项目"):
-
`Avalonia` 解决方案文件夹下:`HandyControl_Avalonia`、`HandyControlDemo_Avalonia`(写死 net10);
-
`Net_40` 解决方案文件夹下:`HandyControl_Net_40`、`HandyControlDemo_Net_40`(.NET Framework 4.0 老线,可选卸载);
-
保留 `Net_GE45` 下两个工程与 `Shared`。
-
菜单 **生成 → 清理解决方案**,随后 **生成 → 重新生成解决方案**。
-
右键 `HandyControlDemo_Net_GE45` →"设为启动项目",工具栏目标框架选 `net9.0-windows`,配置 `Debug`、平台 `Any CPU`。
-
按 **F5**(调试)或 **Ctrl+F5**(直接运行)。
4.1 若重新生成成功、但 XAML 设计器仍有红色波浪线
这是 VS 的设计时缓存,不影响编译运行:
-
先关闭对应 XAML 标签页再重新打开;
-
仍存在则关闭 VS,删除 `src\.vs` 隐藏目录以及各工程下的 `obj`、`bin` 目录,再重新打开并还原、生成。