我遇到了XamlServices序列化/反序列化的麻烦。 我有这门课:
[RuntimeNameProperty("Name")]
[ContentProperty("Children")]
public class Node
{
public Node()
{
}
public string Name { get; set; }
public int Valeur { get; set; }
public Node Parent
{
get;
set;
}
public bool HasChildren
{
get { return mChildren.Count > 0; }
}
public NodeList Children
{
get { return mChildren; }
set { mChildren = value; }
}
NodeList mChildren = new NodeList();
}
NodeList是一个定义为:
的短类public class NodeList : IList<Node>
{
// ... implemented using a List<Node> internally
}
如果我创建一个节点层次结构,如下所示:
Node root = new Node() { Name = "A", Valeur = 2, Parent = null };
root.Children.Add( new Node() { Name = "A1", Valeur = 3, Parent = root } );
root.Children.Add( new Node() { Name = "A2", Valeur = 3, Parent = root } );
root.Children[0].Children.Add( new Node() { Name = "A21", Valeur = 5, Parent = root.Children[0] } );
我按照这种方式序列化:
using( TextWriter writer = File.CreateText( "test.xaml" ) )
{
XamlServices.Save( writer, root );
}
以下是生成的xaml:
<Node Parent="{x:Null}" x:Name="__ReferenceID1" Name="A" Valeur="2"
xmlns="clr-namespace:TestCRTP;assembly=TestCRTP"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Node Parent="{x:Reference A}" x:Name="__ReferenceID0" Name="A1" Valeur="3">
<Node Parent="{x:Reference A1}" Name="A21" Valeur="5">
<NodeList />
</Node>
</Node>
<Node Parent="{x:Reference A}" Name="A2" Valeur="3">
<NodeList />
</Node>
</Node>
正如你所看到的,XamlServices正在生成“__ReferenceID0”属性,它不应该这样做,因为它有RuntimeNameProperty属性......显然,它是因为x:Reference(由于父关系)而这样做,但最有趣的是它甚至没有使用生成的x:名字!!当然,当我尝试反序列化时,它会变得更糟:
using( TextReader reader = File.OpenText( "test.xaml" ) )
{
Node node = XamlServices.Load( reader ) as Node;
}
我已经在“节点”上设置了错误“''Name'属性”,这是合乎逻辑的,因为确实已经有了一个名字....
有任何线索吗?
答案 0 :(得分:1)
只有两个解决方案,您必须将Name属性更改为XName或其他非“Name”的内容。
或者你必须关闭父序列化,
[DesignerSerializability(DesignerSerializability.Hidden)]
public Node Parent
{
get;
set;
}
但在这种情况下,您必须处理节点并在加载对象图后手动设置父节点。
原因XAML这样做是为了序列化彼此连接的对象图,而不仅仅是树。它使用Name来唯一标识节点,但是它的内部逻辑现在允许您在尝试解析引用名称时使用属性Name。