2

我有一个描述如何为用户输入构建 UI 元素的 XML 文档,并且我有包含一些数据和 XPath 表达式的数据对象。我有一个数据对象类型的 DataTemplate,它使用 HierarchicalDataTemplate 来构建基于 XML 的 UI,但我只想使用 XML 的一个子集。如果 XPath 表达式是静态的,我可以写:

<TreeView ItemsSource="{Binding Source={StaticResource dataProvider},
    XPath=/Static/XPath/Expression/*}" />

由于 XPath 表达式来自数据对象,因此使用数据绑定会很方便:

<TreeView ItemsSource="{Binding Source={StaticResource dataProvider},
    XPath={Binding Path=Data.XPathExpression}}" />

不幸的是,Binding MarkupExtension 不是从 DependencyObject 继承的,所以它的属性不是 DependencyProperty 并且不支持数据绑定。

绑定到 XML 数据时如何应用动态 XPath 表达式?

4

1 回答 1

0

您可以创建一个 IMultiValueConverter,将 XML 数据和 XPath 表达式转换为新的 XML 数据:

public object Convert(object[] values, Type targetType, object parameter,
    CultureInfo culture)
{
    try
    {
        if (values.Length < 2) { return null; }

        var data = values[0] as IEnumerable;
        if (data == null) { return null; }

        var xPathExpression = values[1] as string;
        if (xPathExpression == null) { return null; }

        XmlDocument xmlDocument = data.Cast<XmlNode>()
            .Where(node => node.OwnerDocument != null)
            .Select(node => node.OwnerDocument)
            .FirstOrDefault();

        return (xmlDocument == null) ? null : 
            xmlDocument.SelectNodes(xPathExpression);
    }
    catch (Exception) { return null; }
}

public object[] ConvertBack(object value, Type[] targetTypes,
    object parameter, System.Globalization.CultureInfo culture)
{
    throw new NotImplementedException();
}

然后,使用 MultiBinding 将 ItemsSource 绑定到 XML 数据和带有转换器的动态 XPathExpression:

<TreeView>
    <TreeView.Resources>
        <this:XmlXPathConverter x:Key="xmlXPathConverter" />
    </TreeView.Resources>
    <TreeView.ItemsSource>
        <MultiBinding Converter="{StaticResource xmlXPathConverter}">
            <Binding Source="{StaticResource dataProvider}" />
            <Binding Path="Data.XPathExpression" />
        </MultiBinding>
    </TreeView.ItemsSource>
</TreeView>
于 2012-10-23T20:26:37.783 回答