将XML绑定到ItemsSource时应用动态XPath表达式 [英] Apply a dynamic XPath expression when binding XML to ItemsSource

查看:110
本文介绍了将XML绑定到ItemsSource时应用动态XPath表达式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

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

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

不幸的是,绑定标记扩展不会从DependencyObject继承,所以它的属性不是DependencyProperty和don不支持数据绑定。



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

解决方案

您可以创建一个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(异常){return null; }
$ b public object [] ConvertBack(object value,Type [] targetTypes,
object parameter,System.Globalization.CultureInfo culture)
{
抛出新的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>


I have an XML document that describes how to build UI elements for user input, and I have data objects that contain some data and an XPath expression. I have a DataTemplate for the data object type that uses a HierarchicalDataTemplate to build the UI based on the XML, but I only want to use a subset of the XML. If the XPath expression were static, I could just write:

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

Since the XPath expression comes from a data object, it would be convenient to use data binding:

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

Unfortunately, the Binding MarkupExtension doesn't inherit from DependencyObject, so it's properties aren't DependencyProperty and don't support data binding.

How can I apply a dynamic XPath expression when binding to XML data?

解决方案

You can create a IMultiValueConverter that converts the XML data and XPath expression into new XML data:

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();
}

Then, use MultiBinding to bind the ItemsSource to the XML data and a dynamic XPathExpression with the converter:

<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>

这篇关于将XML绑定到ItemsSource时应用动态XPath表达式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆