如何将控件绑定到 ViewModel 中 XmlDocument 的元素(MVVM 模式)?

发布于 2024-10-13 23:08:10 字数 1212 浏览 2 评论 0原文

我正在尝试将 TextBlock 绑定到 XML 文档的元素,如果源是 StaticResouce,则它可以正常工作,但是当通过以下方式公开时,我无法弄清楚绑定到同一 XML 文档的语法:视图模型。

下面是 XML 文档:

<Books>
    <Book ID="1" Name="ABC" />
    <Book ID="2" Name="DEF" />
    <Book ID="3" Name="XYZ" />
</Books>

绑定到 StaticResource = SUCCESSFUL

资源文件包含引用 Books.xml 的 XmlDataProvider:

<XmlDataProvider x:Key="data" Source="Books.xml"/>

下面是我绑定到 xml 文件的方式。

<TextBlock Text="{Binding Source={StaticResource data},XPath=/Books/Book/@Name}"/>
<XmlDataProvider x:Key="data" Source="../Views/Data.xml" />

正如我之前所说,上面的绑定工作正常并且显示“ABC”。但是,该 XmlDocument 应该来自 SQL Server 并通过 ViewModel(MVVM 模式)公开。

绑定到 ViewModel = FAILED

ViewModel 中的 Books 属性填充了完全相同的 XML(见上文):

public XmlDocument Books { get; set; }

这是我用来绑定到 ViewModel 的语法:

<TextBlock Text="{Binding Books,XPath=/Books/Book/@Name}" />

它不返回任何内容我收到以下错误消息:

带有 XPath 的 BindingExpression 无法绑定到非 XML 对象。

非常感谢任何帮助。

I'm trying to bind a TextBlock to an element of a XML document, it works fine if the source is a StaticResouce, but I cannot figure out the syntax to bind to the same XML document when exposed through ViewModel.

Here's the XML document:

<Books>
    <Book ID="1" Name="ABC" />
    <Book ID="2" Name="DEF" />
    <Book ID="3" Name="XYZ" />
</Books>

Binding to a StaticResource = SUCCESSFUL

The resource file contains a XmlDataProvider with reference to Books.xml:

<XmlDataProvider x:Key="data" Source="Books.xml"/>

And here's how I'm binding to the xml file.

<TextBlock Text="{Binding Source={StaticResource data},XPath=/Books/Book/@Name}"/>
<XmlDataProvider x:Key="data" Source="../Views/Data.xml" />

As I said before, the binding above works fine and it displays "ABC". However, that XmlDocument is supposed to come from SQL Server and exposed through ViewModel (MVVM Pattern).

Binding to ViewModel = FAILED

The Books property from the ViewModel is populated with the exactly same XML (see above):

public XmlDocument Books { get; set; }

And here's the syntax that I'm using to bind to ViewModel:

<TextBlock Text="{Binding Books,XPath=/Books/Book/@Name}" />

It doesn't return anything and I'm getting the following error message:

BindingExpression with XPath cannot bind to non-XML object.

Any help is greatly appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

蓦然回首 2024-10-20 23:08:10

在绑定到 StaticResource 的示例中,您的绑定路径指向“适应”您的 XmlDocument 的 XmlDataProvider。而在 ViewModel 示例中,您的 Path 是 XmlDocument 本身。要从 ViewModel 实现等效绑定,该属性需要公开 XmlDataProvider。

In your example where you bind to a StaticResource, your Binding Path points to an XmlDataProvider which 'adapts' your XmlDocument. Whereas in your ViewModel example, your Path is the XmlDocument itself. To achieve an equivalent binding from your ViewModel, the property needs to expose a XmlDataProvider.

北笙凉宸 2024-10-20 23:08:10

我在另一个讨论区找到了答案。下面介绍了如何将控件绑定到 ViewModel 中的 XMLDocument 属性。

<TextBlock DataContext="{Binding Books}" Text="{Binding XPath=/Books/Book/@Name}"/>

现在我可以成功绑定到来自 SQL Server 的 XML 结果。希望能帮助其他有类似问题的人。干杯。

I found the answer on another discussion board. Here's how to bind the control to the XMLDocument property in the ViewModel.

<TextBlock DataContext="{Binding Books}" Text="{Binding XPath=/Books/Book/@Name}"/>

Now I can successfully bind to the XML results coming from SQL Server. Hope that help others with a similar problem. Cheers.

风苍溪 2024-10-20 23:08:10

ColinE已经完全回答了这个问题。但另一个解决方案是公开 BookName 属性。

public class ViewModel
{
    public ViewModel(XDocument doc)
    {
        this.Document = doc;
    }

    private XDocument Document
    {
        get;
        set;
    }

    public string BookName
    {
        get
        {
            return this.Document
                       .Element("Books")
                       .Element("Book")
                       .Attribute("Name").Value;
        }
    }

然后你应该直接绑定到 Name 属性:

<TextBlock Text="{Binding BookName}" />

ColinE has completely answered the question. But the other solution consists in exposing property BookName.

public class ViewModel
{
    public ViewModel(XDocument doc)
    {
        this.Document = doc;
    }

    private XDocument Document
    {
        get;
        set;
    }

    public string BookName
    {
        get
        {
            return this.Document
                       .Element("Books")
                       .Element("Book")
                       .Attribute("Name").Value;
        }
    }

Then you should bind directly to Name property:

<TextBlock Text="{Binding BookName}" />
深空失忆 2024-10-20 23:08:10

如果您绑定到代码隐藏中的源,则不需要使用 XPath。简单的路径就可以了。

代码隐藏

this.DataContext = Books;

Xaml

<TextBlock Text="{Binding Path=Name}"

Incase you binding to a source in code-behind, you don't need to use XPath. Simple Path will do.

Code-behind

this.DataContext = Books;

Xaml

<TextBlock Text="{Binding Path=Name}"
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文