1

好的,我对 XAML 和 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 标准,该表达式检索使用此模板的按钮的内容,例如@id={TemplateBinding Button.Content}(如果可能的话),所以如果我创建这样一个文本内容为“他”的按钮',它将检索 XML 文件中的相应数据,例如质量、原子序数等。在 XAML 中指定这样的动态 XPath 并将其绑定到控件模板上的属性的语法是什么?

4

1 回答 1

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();
    }   
}
于 2016-01-24T06:09:27.407 回答