我一直在寻找,寻找和尝试多种东西,只是没有能够弄清楚。这似乎应该是直截了当的,但我不知所措。我正试图从另一个文本框中提取基于值的数据。
它提取的基本XML:
<?xml version="1.0" encoding="UTF-8"?>
<Translations>
<Translation Id="Greeting">
<English>Hello</English>
<French>Bonjour</French>
</Translation>
XAML:
<Window.Resources>
<XmlDataProvider x:Key="TranslationData" Source="F:\Translations.xml" XPath="Translations"/>
</Window.Resources>
<TextBox Name="LanguageTextBox" Text="English" Width="200" />
<TextBox Name="Results" Text="{Binding Source={StaticResource TranslationData}, XPath=*[@Id\=\'Greeting\']/English}" Width="200" />
我尝试在XPath语句中替换单词'英语',以便它使用LanguageTextBox
的值,因此,如果它是'English',它将保持不变,但当更改为'French'时,XPath将如下所示:
{Binding Source={StaticResource TranslationData}, XPath=*[@Id\=\'Greeting\']/French}
2条答案
按热度按时间kxkpmulp1#
底层问题
在您的示例中,您得到了一个根据所选语言而变化的 XPath 查询。这也需要在
XPath
属性上进行绑定,以便对语言选择TextBox
中的更改值做出React,从而创建新的 XPath。但是,这是不可能的,因为Binding
类型中的XPath
属性不是dependency property,而是普通CLR属性,因此它不支持数据绑定。依赖属性可以通过数据绑定引用值。数据绑定通过XAML中的特定标记扩展语法或代码中的Binding对象工作。使用数据绑定时,最终属性值的确定将推迟到运行时,此时将从数据源获取值。
一种数值转换器解决方案
您可以使用value converter,而不是在绑定中使用 XPath,它使用您的
XmlDataProvider
来检索 language 和 key 的文本。您也可以直接加载XmlDocument
,而不需要数据提供程序。两者都支持通过 XPath 进行查询。您可以编写常规的
IValueConverter
或IMultiValueConverter
(支持绑定多个值)。由于您的密钥似乎是硬编码的,我将提供更简单的常规变体,其中密钥可以作为不可绑定的转换器参数提供。大多数代码都包含参数有效性的检查。在核心
SelectLanguageText
方法中,使用 XPath 查询来自数据提供程序的文本,就像在XAML中一样。如果没有翻译,则返回回退文本。ForceLoadXmlDocument
方法用作workaround,因为数据提供程序可能不会立即加载XML文档。在XAML中,您将定义转换器的示例并在绑定中使用它。
替代方案
您可以创建一个专用的翻译提供程序类型,它公开一个通过绑定设置的属性
Language
,就像您的示例中的TextBox
一样。然后你可以暴露一个indexer。可以与用于翻译的密钥绑定。
其逻辑与直接使用数据提供程序或XML文档的转换器非常相似。
备注
TextBox
输入语言。它允许任何值,并需要额外的验证(请参阅转换器中的null或空格检查)。您应该使用ComboBox
或任何其他仅提供可供选择的不同有效值的控件。d6kp6zgx2#
如果你想直接绑定到一个XML文档,你必须使用一个转换器。或者将XML文档反序列化为类。
因为绑定结果基于两个输入(XML文档和用户输入),所以必须使用
MultiBinding
:以下示例显示如何基于用户选择的属性值(
Translation.Id
)提取XML对象。Translation
XML对象的Id
Map到翻译类别(实际属性值),该类别使用ComboBox
呈现给用户。该语言还使用ComboBox
呈现给用户。基于所选择的值,我们提取所选择的类别的适当翻译(例如
Greeting
)和语言(例如English
)。这个例子使用LINQ to XML而不是
XmlDataProvider
来更方便地遍历XML文档树:Translations.xml
MainWindow.xaml
MainWindow.xaml.cs