如何解析具有自定义类的xaml文件,以获取所有对象的列表?

发布于 2024-12-12 11:10:58 字数 2839 浏览 0 评论 0原文

我浏览了大量类似的帖子,但似乎对我来说没有任何作用。我想要做的就是加载一个 xaml 文件(位于其他某个程序集中),并迭代不同的元素/对象以检查某个属性值。 我可以将其作为一个简单的 XML 文件来读取,但是样式等内容无法通过 xml 解析来捕获。 经过大量搜索后,我尝试了以下两件事:

  1. 我从 xaml 中删除了 x:Class=".." 我还在其中添加了 assembly=XBase.UI (因为我原来的 xaml 没有这个,并且我读到动态加载时,您需要知道指定程序集) 然后我将剩余的文件作为 xml 流加载。 然后我调用 XamlReader.Load(stream)

这似乎适用于发布查询的人,但我得到了异常

'System.Windows.Markup.XamlParseException : 'The invocation of the constructor on type 'XBase.UI.XControlBase' that matches the specified binding constraints threw an exception.' Line number '6' and line position '55'.
  ----> System.InvalidOperationException : The calling thread must be STA, because many UI components require this.'

我尝试的第二件事是使用 XamlReader.Parse 并提供 ParserContext 。 这就是我所做的:

   var context = new ParserContext();
   context.XamlTypeMapper = new XamlTypeMapper(new string[] { });
   context.XamlTypeMapper.AddMappingProcessingInstruction("UI", "XBase.UI", ""); //assemblyname is empty as my original file doesn't have one
   context.XmlnsDictionary.Add("UI", "clr-namespace:XBase.UI;assembly=XBase.UI");
   string text = File.ReadAllText(xamlfile);
   var object = XamlReader.Parse(xamlfile, context);

这也引发了异常:

'System.Windows.Markup.XamlParseException : 'Cannot create unknown type '{clr-namespace:XBase.UI}XControlBase'.' Line number '1' and line position '2'.
  ----> System.Xaml.XamlObjectWriterException : 'Cannot create unknown type '{clr-namespace:XBase.UI}XControlBase'.' Line number '1' and line position '2'.'

我的原始 xaml 文件

<UI:XControlBase x:Class="XBase.UI.XListView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
xmlns:UI="clr-namespace:XBase.UI" Height="Auto" Width="Auto" IsTabStop="False"
mc:Ignorable="d"
Visibility="{Binding IsVisible, Converter={StaticResource VisibilityConverter}}">
<UI:XControlBase.Resources>
    <UI:ButtonTemplateSelector x:Key="ButtonSelector" />
</UI:XControlBase.Resources>
<UI:ItemControlWrapper  
    ItemsSource="{Binding ButtonList}" 
    ItemTemplateSelector="{StaticResource ButtonSelector}" 
    IsTabStop="False">
    <UI:ItemControlWrapper.ItemsPanel>
        <ItemsPanelTemplate >
            <StackPanel Orientation="{Binding ListOrientation}" />
        </ItemsPanelTemplate>
    </UI:ItemControlWrapper.ItemsPanel>
</UI:ItemControlWrapper>
</UI:XControlBase>

请在这里帮助我。我什至不确定这是否是实现我想要的目标的正确方法。如果有另一种方法可以以更有意义的方式列出某种类型的所有元素,而不是 XmlDocument 的 GetElementsByTagName,请告诉我。

提前致谢!

I went through the tons of similar posts but nothing seems to work in my case. All I want to do is load a xaml file (located in some other assembly), and iterate through the different elements/objects to check for a certain attribute value.
I could have read it as a simple XML file, but things like styles etc cannot be caught through xml parsing.
After searching a lot,I tried the following two things:

  1. I removed the x:Class=".." from the xaml
    I also added the assembly=XBase.UI in this ( as my original xaml didn't have this and I read that when loading dynamically, you need to know specify the assembly)
    then I loaded the remaining file as xml stream.
    Then I called XamlReader.Load(stream)

This seems to work for people who posted queries, but I get exception

'System.Windows.Markup.XamlParseException : 'The invocation of the constructor on type 'XBase.UI.XControlBase' that matches the specified binding constraints threw an exception.' Line number '6' and line position '55'.
  ----> System.InvalidOperationException : The calling thread must be STA, because many UI components require this.'

The second thing I tried was to use the XamlReader.Parse and provide the ParserContext along with it.
This is what I did:

   var context = new ParserContext();
   context.XamlTypeMapper = new XamlTypeMapper(new string[] { });
   context.XamlTypeMapper.AddMappingProcessingInstruction("UI", "XBase.UI", ""); //assemblyname is empty as my original file doesn't have one
   context.XmlnsDictionary.Add("UI", "clr-namespace:XBase.UI;assembly=XBase.UI");
   string text = File.ReadAllText(xamlfile);
   var object = XamlReader.Parse(xamlfile, context);

This too throws an exception:

'System.Windows.Markup.XamlParseException : 'Cannot create unknown type '{clr-namespace:XBase.UI}XControlBase'.' Line number '1' and line position '2'.
  ----> System.Xaml.XamlObjectWriterException : 'Cannot create unknown type '{clr-namespace:XBase.UI}XControlBase'.' Line number '1' and line position '2'.'

My original xaml file

<UI:XControlBase x:Class="XBase.UI.XListView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
xmlns:UI="clr-namespace:XBase.UI" Height="Auto" Width="Auto" IsTabStop="False"
mc:Ignorable="d"
Visibility="{Binding IsVisible, Converter={StaticResource VisibilityConverter}}">
<UI:XControlBase.Resources>
    <UI:ButtonTemplateSelector x:Key="ButtonSelector" />
</UI:XControlBase.Resources>
<UI:ItemControlWrapper  
    ItemsSource="{Binding ButtonList}" 
    ItemTemplateSelector="{StaticResource ButtonSelector}" 
    IsTabStop="False">
    <UI:ItemControlWrapper.ItemsPanel>
        <ItemsPanelTemplate >
            <StackPanel Orientation="{Binding ListOrientation}" />
        </ItemsPanelTemplate>
    </UI:ItemControlWrapper.ItemsPanel>
</UI:ItemControlWrapper>
</UI:XControlBase>

Please help me out here. I am not even sure if this is the right way to achieve what I want. If there is another way to list all of the elements of certain kind in a more meaningful way other than
the XmlDocument's GetElementsByTagName, please let me know.

Thanks in advance!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文