通过动态Xpath表达式在控件模板中进行XAML数据绑定

时间:2012-04-04 16:20:36

标签: wpf xaml xpath

好的,我对XAML& amp; WPF,所以我正在尝试一个学习项目来构建一个周期表。我有一组XML中的元素数据。我在XAML中定义了一个控件模板,将每个化学元素的信息显示为网格中的一个按钮:

 <ControlTemplate x:Key="elementTemplate" TargetType="{x:Type Button}">
            <Grid>
                <Rectangle x:Name="backingRect" Margin="2" StrokeThickness="0" RadiusX="3" RadiusY="3" Fill="{TemplateBinding Property=Button.Background}">
                    <Rectangle.Effect>
                        <DropShadowEffect BlurRadius="8"/>
                    </Rectangle.Effect>

                </Rectangle>
                <Viewbox>
                    <Grid>
                        <Grid.RowDefinitions>
                            <RowDefinition Height="0.2*"/>
                            <RowDefinition Height="*"/>
                            <RowDefinition Height="0.2*"/>
                        </Grid.RowDefinitions>
                        <TextBlock FontWeight="DemiBold" TextAlignment="Center" Grid.Row="0" diag:PresentationTraceSources.TraceLevel="High">
                            <TextBlock.Text>
                                <Binding Source="{StaticResource elementData}">

                                    <Binding.XPath>atom[@id='H']/scalar[@dictRef='bo:atomicNumber']</Binding.XPath>
                                </Binding>
                            </TextBlock.Text>
                        </TextBlock>
                        <TextBlock FontWeight="Bold" TextAlignment="Center" FontSize="28" Grid.Row="1" >  
                            <TextBlock.Text>
                                <Binding Source="{StaticResource elementData}" >

                                    <Binding.XPath>atom[@id='H']/label[@dictRef='bo:symbol']/@value</Binding.XPath>
                                </Binding>
                            </TextBlock.Text></TextBlock >
                        <TextBlock FontWeight="DemiBold" TextAlignment="Center" Grid.Row="2">1.0021</TextBlock>
                    </Grid>
                </Viewbox>
            </Grid>               
</ControlTemplate>

现在,这将创建一个静态绑定到我的基础XML数据的按钮。我想要做的是用一个表达式替换@id='H' XPath标准,该表达式检索使用此模板的Button的内容,如@id={TemplateBinding Button.Content}(如果可能的话),所以如果我创建这样一个文本内容为'He'的Button,它将检索XML文件中的相应数据,如质量,原子序数等。在XAML中指定这样一个动态XPath并将其绑定到一个属性的语法是什么控制模板?

1 个答案:

答案 0 :(得分:1)

有关更全面的讨论,请参阅http://www.codeproject.com/Articles/854564/Parameterized-XPaths-in-XAML

基本上,您必须使用多绑定转换器,在构造绑定时执行参数化路径替换,然后返回所需内容。

E.g.
<MultiBinding Converter="{StaticResource XPathConverter}" ConverterParameter="atom[@id=&quot;{1}&quot;]/scalar[@dictRef='bo:atomicNumber']" Mode="OneWay">
    <Binding Source="{StaticResource elementData}" Mode="OneWay" />
    <Binding ElementName="_Button" Path="Content" Mode="OneWay"/>
</MultiBinding>

如果您只需要OneWay绑定,转换器很简单。 ConverterParamenter是带有参数化占位符的XPath。第一个绑定是您的XML数据。第二个绑定是您的控制数据用于参数化替换。您必须更正下面的转换器,以获取特定数据对象和所需的返回值。

public class XPathConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        XmlNode root = (value[0] as XmlNode);
        string xpathf = (parameter as string);
        for (int i = 1; i < values.Count(); i++)
            xpathf = xpathf.Replace("{" + i.ToString().Trim() + "}", values[i] as string ?? "");

        return root.SelectSingleNode(xpathf).InnerXML;
     }

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