Silverlight 5+RIA迁移WPF时出现XAML生成错误求助
SL5迁移WPF项目XAML生成错误修复方案
问题背景
当前正在推进SL5+RIA服务到WPF前端+WCF服务的临时方案迁移,目前已完成所有Silverlight组件、类库到WPF对应项的适配调整,迁移过程中遇到3个关联的Visual Studio XAML生成错误。
环境信息
- 原有Silverlight解决方案:基于VS 2015(版本号14.0.25431.01)维护,采用SL5 + .NET 4.0框架,全量清理后可正常生成
- 新建WPF解决方案:基于VS 2019(版本号16.11.15)搭建,采用.NET 4.8框架
报错详情
部分用户控件编译时抛出3个错误:
- 错误XDG0036:
The "Key" attribute can only be used on an element that is contained in "IDictionary",错误指向XAML第1行(UserControl自身定义行),对应代码片段:
<UserControl x:Class="Inspectieprogramma.UserControls.DetailsInspfreq" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation" xmlns:converters="clr-namespace:Inspectieprogramma.Converters" xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity" xmlns:cmdExtras="http://www.galasoft.ch/mvvmlight" xmlns:helpers="clr-namespace:Inspectieprogramma.Helpers" xmlns:sys="clr-namespace:System;assembly=mscorlib" >
- 错误XDG0040:
The property "Resources" can only be set once,错误指向<UserControl.Resources>起始标签,但代码中仅存在1处资源声明,对应XAML结构:
<UserControl ...> <UserControl.DataContext> <Binding Path="Inspectieprogramma" Source="{StaticResource Locator}" /> </UserControl.DataContext> <UserControl.Resources> <ResourceDictionary> <ResourceDictionary.MergedDictionaries> <ResourceDictionary Source="/Inspectieprogramma;component/Styles/RadDatetimePickerStyle.xaml" /> </ResourceDictionary.MergedDictionaries> </ResourceDictionary> <!-- 此处为DataTemplate、ControlTemplate、Style定义 --> </UserControl.Resources> <Border> <!-- 页面所有内容 --> </Border> </UserControl>
- 错误XDG0047:
The specified value cannot be assigned. The following type was expected: "ResourceDictionary",错误指向位置和XDG0036一致,为XAML第1行。
根因与修复方案
三个错误属于WPF XAML解析器的连锁报错,核心原因是Silverlight与WPF的资源字典语法规则存在差异:
Silverlight的XAML解析器允许在<UserControl.Resources>节点下先写显式<ResourceDictionary>标签声明合并字典,再在该标签外部直接放置其他资源;但WPF的XAML解析器不支持这种写法,会判定Resources属性被重复赋值、值类型不符合ResourceDictionary要求,最终连锁抛出三个错误。
修复操作如下:
- 把所有放在
</ResourceDictionary>闭合标签外的Style、DataTemplate、ControlTemplate资源,全部移动到<ResourceDictionary>标签内部,与ResourceDictionary.MergedDictionaries节点同级 - 修正后的资源段结构参考:
<UserControl.Resources> <ResourceDictionary> <ResourceDictionary.MergedDictionaries> <ResourceDictionary Source="/Inspectieprogramma;component/Styles/RadDatetimePickerStyle.xaml" /> </ResourceDictionary.MergedDictionaries> <!-- 所有资源统一放在ResourceDictionary内部 --> <Style TargetType="Button" x:Key="TestBtnStyle"> <!-- 样式内容 --> </Style> <DataTemplate x:Key="ItemTemplate"> <!-- 模板内容 --> </DataTemplate> </ResourceDictionary> </UserControl.Resources>
- 完成修改后,清理解决方案,删除项目obj、bin目录下的缓存文件,重新生成即可消除全部编译错误。
如果修改后XAML设计器仍显示红线报错,但项目可以正常编译,关闭当前XAML文件标签后重新打开即可刷新设计器缓存。
内容的提问来源于stack exchange,提问作者Emmanuel Nuyttens
相关产品推荐
相关产品推荐

