- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在使用 XAML 序列化一些对象,它在大多数情况下工作得很好。
我现在面临的问题是,当我更改数据结构时,所有旧对象都会产生如下所示的异常。我不介意这些值是否丢失。
有没有办法关闭这些异常,让 xaml 阅读器忽略未知属性?如果现在没有办法做到这一点,新的 System.Xaml 命名空间中是否有可以做到这一点的东西?
System.Windows.Markup.XamlParseException: The property 'BorderPadding' does not exist in XML namespace 'clr-namespace:TemplateGenerator;assembly=App_Code'. Line '1' Position '158'.
at System.Windows.Markup.XamlParser.ThrowExceptionWithLine(String message, Int32 lineNumber, Int32 linePosition)
at System.Windows.Markup.XamlParser.ThrowException(String id, String value1, String value2, Int32 lineNumber, Int32 linePosition)
at System.Windows.Markup.XamlParser.WriteUnknownAttribute(XamlUnknownAttributeNode xamlUnknownAttributeNode)
at System.Windows.Markup.XamlParser.ProcessXamlNode(XamlNode xamlNode, Boolean& cleanup, Boolean& done)
at System.Windows.Markup.XamlParser.ReadXaml(Boolean singleRecordMode)
at System.Windows.Markup.TreeBuilderXamlTranslator._Parse()
at System.Windows.Markup.XamlParser.Parse()
at System.Windows.Markup.XamlTreeBuilder.ParseFragment()
at System.Windows.Markup.TreeBuilder.Parse()
at System.Windows.Markup.XamlReader.XmlTreeBuildDefault(ParserContext pc, XmlReader reader, Boolean wrapWithMarkupCompatReader, XamlParseMode parseMode, Boolean etwTracingEnabled)
at System.Windows.Markup.XamlReader.Load(XmlReader reader)
at System.Windows.Markup.XamlReader.Parse(String xamlText)
最佳答案
事实证明,实现起来并不像乍看起来那么难。这里的关键信息是提到的异常不是由 XamlReader
引发的,而是由 XamlObjectWriter
引发的,它负责使用 XamlReader
和创建和填充结果对象。因此,我们需要做的就是提供一个自定义的 XamlReader
,它可以简单地跳过未知属性。在我看来,最通用的方法是创建一个可以环绕另一个(任意)阅读器的阅读器。这个想法可以概括如下:
Read
方法中,我们从底层阅读器读取了一次XamlReader.NodeType
是 StartMember
,就可以通过检查 XamlReader.Member.IsUnknown
轻松确定,我们简单地继续阅读直到我们到达成员定义的末尾(一个相应的1 EndMember
节点)并通过再次阅读移动到下一个节点;如果下一个节点也是未知属性,我们重复该过程这样,对 Read
的单个调用将跳过未知属性,可能会导致从底层读取器进行多次读取,但这种行为对消费者来说是透明的。
这是一个示例代码:
public class LaxXamlReader : XamlReader
{
public override bool Read()
{
//Read once from the underlying reader
_Reader.Read();
//Check if current node is an unknown property
while (NodeType == XamlNodeType.StartMember && Member.IsUnknown)
{
//We need to track member nesting level so that we can correctly
//identify the corresponding EndMember node
var level = 1;
while (level > 0)
{
_Reader.Read();
if (NodeType == XamlNodeType.StartMember)
level++;
else if (NodeType == XamlNodeType.EndMember)
level--;
}
//At this point we're at the corresponsing EndMember node, so we
//advance to the next node; if it's also an unknown property, it
//will be caught by the while loop
_Reader.Read();
}
//If we've reached the end of input return false
return !IsEof;
}
public override XamlReader ReadSubtree()
=> new LaxXamlReader(_Reader.ReadSubtree());
protected override void Dispose(bool disposing)
{
//Only dispose the underlying reader if Dispose() was called;
//otherwise let GC do the job
if (disposing)
((IDisposable)_Reader).Dispose();
base.Dispose(disposing);
}
//The code below simply forwards the functionality from the underlying reader
public LaxXamlReader(XamlReader reader)
{
_Reader = reader;
}
private readonly XamlReader _Reader;
public override bool IsEof => _Reader.IsEof;
public override XamlMember Member => _Reader.Member;
public override NamespaceDeclaration Namespace => _Reader.Namespace;
public override XamlNodeType NodeType => _Reader.NodeType;
public override XamlSchemaContext SchemaContext => _Reader.SchemaContext;
public override XamlType Type => _Reader.Type;
public override object Value => _Reader.Value;
public override void Skip() => _Reader.Skip();
}
使用示例:
var xaml = "<Object Foo=\"Bar\" xmlns=\"clr-namespace:System;assembly=mscorlib\" />";
var obj = XamlServices.Load(new LaxXamlReader(new XamlXmlReader(new StringReader(xaml))));
请注意,XamlReader
(以及其他提到的 XAML 相关类型)是在 System.Xaml
命名空间中定义的类型。
1 由于XAML中的属性可以写成元素并包含具有自身属性的对象,我们需要忽略对应于EndMember
的节点这些嵌套属性
关于c# - 如何让 XamlReader.Parse 不抛出 "property does not exist"XamlParseException?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1500198/
我知道对于具有指定 clr-namespace: 和 assembly= 标记的控件,XamlReader 只是在指定的程序集中查找该类型。 但是默认命名空间 xmlns="http://schema
在运行时使用DataTemplateSelector创建列。 XamlReader.Load处有异常:System.Windows.StaticResourceExtension。如何加载资源? va
我现在有一个带有德语变音符号(见下文)的 xaml,当我尝试解析它时,我收到了一个无效字符错误。 当我不使用 XamlParser 上下文时,它会起作用。但是我必须使用它来设置一些类型映射 XAML:
我现在有一个带有德语变音符号(见下文)的 xaml,当我尝试解析它时,我收到了一个无效字符错误。 当我不使用 XamlParser 上下文时,它会起作用。但是我必须使用它来设置一些类型映射 XAML:
我正在 WPF (.Net 3.5) 中创建一个应用程序,我希望能够根据每个客户端对其进行自定义。我将资源提取到外部 xaml(主题)文件中。将 xaml 文件构建为 Page,效果非常好。 现在我想
我正在尝试加载 foillowing xaml: 在我
我正在尝试加载 foillowing xaml: 在我
在我们的应用中,无论对象的类型如何,我们都需要将对象的属性以propertyName、propertyValue、propertyType的形式保存到同一个数据库表中。我们决定使用 XamlWrite
我有一些 Xaml 对象的字符串表示形式,我想构建控件。我正在使用 XamlReader.Parse功能来做到这一点。对于一个简单的控件,例如 Button,它有一个不带任何参数的默认构造函数,这工作
我正在尝试从 xaml 生成我自己的自定义磁贴。我已将一些代码从 C++ 转换为 C#,以便将其集成到我的应用程序中。 基本上我有这个方法: async Task GenerateHighResTil
我在 (UIElement)XamlReader.Load(...) 期间得到一个异常 'Cannot create unknown type 'TextBox'.' Line number '1'
F# 不支持部分类,也不支持 XAML 文件的预编译。解决方法:在运行时加载图形对象定义,而不是后面的编译时代码。有多种方法可以为 XamlReader 提供引用资源文件的内容。 open Syste
XamlReader正在使用本地程序集和 WPF 程序集中定义的类型加载 Xaml,没有任何问题。 如果我包含在外部程序集中定义的类型,那么 XamlParseException抛出以下消息。 Can
我正在尝试在我的 WPF 项目中实现下面的代码,以便为具有动态列的 DataGrid 动态生成 DataTemplates。我在 StackOverflow here 上找到了代码 public Da
我正在使用 XamlReader.Parse(string) 动态构建我的数据模板。我遇到的问题是我无法将任何事件放在我使用 XamlReader 创建的任何控件上。在网上做了一些研究后,我了解到这是
与 earlier question 有关我问过,我看到有 LoadComponent() 和 XamlReader.Load()。它们非常相似,以至于我不太确定在什么情况下应该使用哪一个。 那么,从
我有一个程序,用户可以在其中查看保存在 XAML 中的各种 3D 模型,然后使用 TrackballDecorator 操作 Viewport3D。这些 XAML 文件中包含转换,我使用问题 WPF
WPF 应用程序具有使用 XamlReader.Load() 方法从单独的文件加载用户控件的操作: StreamReader mysr = new StreamReader(pathToFile);
我正在玩 .net 4 System.Windows.Markup.XamlReader - 就像一个教育练习 - 我一直遇到同样的问题:用 XamlReader.Load 加载 xaml抛出一个 X
我正在构建一个通用 WP7 程序集,它将显示我的应用程序的通用帮助/关于信息,每个应用程序程序集将指定一对 StackPanels,其中包含一些应用程序特定信息(称为 em Legal.xaml 和
我是一名优秀的程序员,十分优秀!