XAMLParser 创建的 DataTemplate:引用 StaticResource 的正确方法

XAMLParser-created DataTemplate: Correct way to reference a StaticResource

我正在使用 XamlReader 在代码中创建 DataTemplate:

public DataTemplate CreateDataTemplate()
{
    string template = @"<DataTemplate >
                            <StackPanel>        
                                <ComboBox ItemsSource=""{Binding Source={StaticResource collectibleTypeFromEnum}}"" />              
                            </StackPanel>
                        </DataTemplate>";

    ParserContext context = new ParserContext();
    context.XamlTypeMapper = new XamlTypeMapper(new string[0]);
    context.XmlnsDictionary.Add("", "http://schemas.microsoft.com/winfx/2006/xaml/presentation");
    context.XmlnsDictionary.Add("x", "http://schemas.microsoft.com/winfx/2006/xaml");

    // This is meant to provide reference to where collectibleTypeFromEnum lives
    context.XamlTypeMapper.AddMappingProcessingInstruction("myview", "MyProgram.View", "MyProgram, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null");
    context.XmlnsDictionary.Add("myview", "myview");

    return XamlReader.Parse(template, context) as DataTemplate;
}

XAML解析器成功解析了字符串和returns DataTemplate,但它随后在运行时崩溃('System.Windows.Markup.XamlParseException':"Provide value on 'System.Windows.Markup.StaticResourceHolder'")。我需要帮助提供对该 StaticResource 的正确引用,但我无法弄清楚。

我正在尝试通过 ParserContext(见上文)提供正确的 namespace/reference,但显然我做错了。如果我从 XAML 检索 ObjectDataProvider 并将其添加到应用程序的全局资源中(Application.Current.Resources.Add()),一切正常。但是在我看来,我应该可以直接引用 XAML 资源。

有问题的转换器是在用户控件中定义的(与 DataTemplate 最初所在的控件相同,因此 DT 可以毫无问题地找到它):

<UserControl x:Class="MyProgram.View.CollectibleDetail"
             [...] >
    <UserControl.Resources>
    <ObjectDataProvider x:Key="collectibleTypeFromEnum" MethodName="GetValues" ObjectType="{x:Type System:Enum}">
        <ObjectDataProvider.MethodParameters>
            <x:Type TypeName="model:ECollectibleType"/>
        </ObjectDataProvider.MethodParameters>
    </ObjectDataProvider>
</UserControl.Resources>

StaticResource 不支持前向引用。您可以将资源添加到 Application.Current.Resources 以使其在整个应用程序中可用,或者您可以使用 {DynamicResource}:

string template = @"<DataTemplate >
                    <StackPanel>        
                        <ComboBox ItemsSource=""{DynamicResource collectibleTypeFromEnum}"" />              
                    </StackPanel>
                </DataTemplate>";