xaml 资源字典中的自定义属性

Custom attributes in xaml resourcedictionary

我有一个 xaml 资源字典如下

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:sys="clr-namespace:System;assembly=mscorlib"
                    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
                    xmlns:loc="http://temp/uri" 
                    mc:Ignorable="loc">
    <sys:String x:Key="ResouceKey" loc:Note="This is a note for the resource.">ResourceText</sys:String>
</ResourceDictionary>

我正在遍历所有 .xaml 文件并尝试转换为 POCO class 并使用 XamlReader 获取 loc:Note 属性。

using (var sr = new StreamReader(...))
{
    var xamlreader = new XamlReader();
    var resourceDictionary = xamlreader.LoadAsync(sr.BaseStream) as ResourceDictionary;
    if (resourceDictionary == null)
    {
        continue;
    }

    foreach (var key in resourceDictionary.Keys)
    {
        // In this loop i would like to get the loc:Note
        var translation = new Translation
            {
                LocaleKey = locale, 
                Note = string.Empty, // How to get the note from the xaml
                Text = resourceDictionary[key] as string
            });
    }
}

这可能吗,还是我必须求助于使用自定义 xml 序列化逻辑?

XamlReader 包含仅包含 key/value 对的词典。除非您创建自己的 class 或类型,否则它将忽略自定义属性。字符串是原始项目,将按原样显示,而不是可能具有其他属性的 class。

只创建一个 class:

会更干净、更安全
public class MyString {
    public string _string { get; set; }
    public string _note { get; set; } 
}

然后将它们存储在您的 ResourceDictionary 中。现在您可以这样转换值:(MyString)r.Values[0] 然后将它们分配给您的 Translation 对象。

最终使用 Xdocument 阅读 xaml 资源。

var xdoc = XDocument.Load(...);
if (xdoc.Root != null)
{
    XNamespace xNs = "http://schemas.microsoft.com/winfx/2006/xaml";
    XNamespace sysNs = "clr-namespace:System;assembly=mscorlib";
    XNamespace locNs = "http://temp/uri";

    foreach (var str in xdoc.Root.Elements(sysNs + "String"))
    {
        var keyAttribute = str.Attribute(xNs + "Key");
        if (keyAttribute == null)
        {
            continue;
        }
        var noteAttribute = str.Attribute(locNs + "Note");

        var translation = new Translation
            {
                LocaleKey = locale,
                Note = noteAttribute != null ? noteAttribute.Value : null,
                Text = str.Value
            });
    }
}