【问题标题】:WPF XPath Binding With Multiple Results Converted to Comma-Delimited String将多个结果转换为逗号分隔字符串的 WPF XPath 绑定
【发布时间】:2009-10-26 18:03:46
【问题描述】:

我有一个类似于以下结构的 XML 文件:

<Parent>
<Child>5</Child>
<Child>3</Child>
<Child>5</Child>
<Child>1</Child>
</Parent>

在我的 XAML 中,我有一个绑定到 XML 文件的 ListView,并设置了要绑定的 ListViewItem 的 DataTemplate,如下所示:

&lt;TextBlock Text="{Binding XPath=Parent/Child}"/&gt;

显然,我希望这个 XPath 查询有 4 个结果,但我似乎找不到将结果转换为逗号分隔字符串的方法,而现在,TextBlock 只显示第一个值。

如果我使用相同的 XPath 查询来设置 ListBox 的 ItemsSource,我会在 ListBox 中获得所有结果,所以我认为我应该能够获得传递给 Converter 类的所有值...

【问题讨论】:

    标签: wpf xml xpath binding


    【解决方案1】:

    没有办法让返回多个节点(例如您的节点)的 XPath 查询为您将它们聚合为单个值。发生的情况是返回了一个节点集,并且由于您绑定到单个字符串属性,因此基础结构只是通过从集合中抓取第一个节点然后抓取它的 @text 节点来强制该节点集。

    老实说,我自己没有尝试过,目前也没有时间,但我希望它能够工作的唯一方法是编写一个自定义的 IValueConverter。我假设它会将 XmlNodeList 作为要转换的值,然后您可以枚举这些节点并自己连接一个逗号分隔的字符串。

    更新

    由于 XPath 引擎进行预强制,IValueConverter 建议不起作用,因此我建议您这样做:与其绑定到单个 TextBlock,不如绑定到 ItemsControl 并将 ItemTemplate 定义为 ItemsControl如下:

    <DataTemplate>
        <TextBlock Text="{Binding}"/>,
    </DataTemplate>
    

    注意:老实说,我在 DataTemplate 中采用了惰性方法,即使在最后一项之后,您也会以逗号结束。也就是说,您应该能够使用触发器定义 DataTemplate,该触发器确定它是最后一项并且不显示逗号。

    最后,根据您希望数据的布局方式,还要设置 ItemsControl 的 ItemsPanel。我假设您想要水平流并在此处换行:

    <ItemsPanelTemplate>
        <WrapPanel Orientation="Horizontal" />
    </ItemsPanelTemplate>
    

    【讨论】:

    • 嗯,恐怕是这样。在我编写的 IValueConverter 中,似乎我传递了一个字符串,但由于它是作为类型对象传递的,我希望调试器正在做一些简单的转换或其他事情。正如我所说,这在绑定 时效果很好,所以我的猜测是在调用 IValueConverter 之前存在强制,我只是无法确认。
    • 不能说我很惊讶。如果他们在幕后使用 SelectNodes(我确信他们是),则将节点集转换为单个值的标准 XPath 转换是从集中获取第一个节点。我将编辑我的答案,并提出第二个关于如何完成此任务的建议。
    • 谢谢,德鲁。我很欣赏后续行动,因为它可能为我节省了一些时间,因为我正在模板化 ListBox (ha) 而不是直接访问源代码 - ItemsControl。
    【解决方案2】:

    如果您想将 XML 数据设置为 ListView 的源,您可以这样做:

    MyListView.ItemsSource = XElement.Load(@"XMLFile1.xml").Elements("Child");
    

    然后你绑定到 TextBlock 中的 Value 属性:

    <TextBlock Text="{Binding Path=Value}" />
    

    如果您需要修改查询,您可以将 XML 文件的内容提取到一个 var 中,该 var 可以用作 ListView 上的 ItemsSource。

    XElement xmlData = XElement.Load(@"XMLFile1.xml");
    var query = from x in xmlData.Elements("Child")
                select x;
    

    【讨论】:

    • 也许,我没有很好地关注你,但我的 ListView 恐怕比单个 ListViewItem 复杂一点。我试图在没有太多代码隐藏的情况下做到这一点,因为它“似乎”应该有一种方法来转换返回多个结果的 XPath 查询。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-02-01
    • 2020-12-20
    • 1970-01-01
    • 2019-11-18
    • 2018-08-16
    • 2013-09-30
    • 1970-01-01
    相关资源
    最近更新 更多