通过 XElement 使用数据绑定 XML 数据更新 TreeView 时出现问题

发布于 2024-12-05 20:08:55 字数 1566 浏览 0 评论 0原文

我有一个在 WPF 中实现的 TreeView,它通过 XElement 类绑定到一些 XML 数据。第一次加载 XML 文件时,绑定工作正常。所有数据都按预期填充树。当我添加和删除元素时会出现问题,因为 TreeView 中没有任何反应。现在我以前已经这样做过”,并且我相信我记得不需要为这项工作正确地做任何额外的工作。至少对于从树中添加和删除项目的简单情况是这样。我记得我很惊讶这不需要任何额外的编码工作就可以工作。我无法再访问该代码,因此我不能只查看我已经做过的事情。所以我有点困惑为什么我现在不能让它工作。

我的WPF代码如下。

<Window.Resources>
    <HierarchicalDataTemplate ItemsSource="{Binding Path=Elements}" x:Key="ViewEditTreeTemplate">
        <StackPanel Orientation="Horizontal" Margin="2">
            <Label x:Name="ElementHeaderLabel" Padding="1" VerticalContentAlignment="Center" FontSize="16" Content="{Binding Path=DisplayName}" />
        </StackPanel>
    </HierarchicalDataTemplate>
</Window.Resources>


<Grid>
    <TreeView  Name="DataTree" ItemTemplate ="{Binding Source={StaticResource ViewEditTreeTemplate}}" Margin="0,0,0,53" />
</Grid>

我将 XML 文档附加在后面的代码中,如下所示。请记住,这似乎有效,因为树可以很好地自动填充 XML 数据中的信息。

XElement NewElement = new XElement(XElement.Load(FilePath));
List<XElement> TempList = new List<XElement>();
TempList.Add(NewElement);
DataTree.ItemsSource = TempList;

在后面的代码中,当我添加或删除元素时,我会执行以下操作:

// When removing an element
Element.Remove();            //Element is of type XElement

// When adding an element
ParentElement.Add(NewElement);    //ParentElement and NewElement are of type XElement

我有一种强烈的感觉,当我之前这样做时,我实际上不需要做任何特别的事情。 .Remove() 和 .Add() 例程以某种方式通知绑定 .Elements() 中的项目已更改并且屏幕自动更新。无论如何,这一次它不起作用。有谁知道为什么?

I have a TreeView implemented in WPF that is bound to some XML data via the XElement class. When loading the XML file the first time the binding works fine. All the data populates the tree as expected. The problem occurs when I add and remove elements because nothing happens in the TreeView. Now I've done this before' and I believe I remember not having to do any extra work for this work correctly. At least for the simple case of adding and removing items from the tree. I remember being surprised that this worked without any extra coding effort. I don't have access to that code anymore so I can't just look at what I already did. So I'm kind of stumped as to why I can't get this to work now.

My WPF code is as follows.

<Window.Resources>
    <HierarchicalDataTemplate ItemsSource="{Binding Path=Elements}" x:Key="ViewEditTreeTemplate">
        <StackPanel Orientation="Horizontal" Margin="2">
            <Label x:Name="ElementHeaderLabel" Padding="1" VerticalContentAlignment="Center" FontSize="16" Content="{Binding Path=DisplayName}" />
        </StackPanel>
    </HierarchicalDataTemplate>
</Window.Resources>


<Grid>
    <TreeView  Name="DataTree" ItemTemplate ="{Binding Source={StaticResource ViewEditTreeTemplate}}" Margin="0,0,0,53" />
</Grid>

I'm attaching my XML document in the code behind as follows. Keep in mind that this appears to be working since the tree auto populates with the information from the XML data just fine.

XElement NewElement = new XElement(XElement.Load(FilePath));
List<XElement> TempList = new List<XElement>();
TempList.Add(NewElement);
DataTree.ItemsSource = TempList;

In the code behind when I go to add or remove elements I do as follows:

// When removing an element
Element.Remove();            //Element is of type XElement

// When adding an element
ParentElement.Add(NewElement);    //ParentElement and NewElement are of type XElement

I have this strong feeling that when I did this before, I actually didn't have to do anything special. The .Remove() and .Add() routines somehow notified the bindings that the items in .Elements() have changed and the screen updated automatically. Whatever the case, its not working this time around. Does anyone know why?

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

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

发布评论

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

评论(1

浪漫人生路 2024-12-12 20:08:55

好吧,我有一个解决方案来解决我自己的问题。我不知道为什么我认为这最初不需要做任何特别的事情就可以工作,但事实似乎并非如此。

为了更清楚地说明问题,我没有按原样使用 XElement 对象,而是将它包装在另一个类中,这样我就可以向它添加更多功能。这很好,因为事实证明我需要 INotifyPropertyChanged 接口并重写一些方法以获得我想要的行为。我的实际类头看起来像这样。

public class TreeElement : XElement, INotifyPropertyChanged
{
   ...
}

由于我的 TreeView 绑定在 XElement.Elements() 例程上,因此当我添加或删除元素时它没有收到通知。原因是因为 XElement.Elements() 不是依赖属性。这是例行公事。我提前知道了这一点,但出于某种原因,我很固执,仍然认为它会起作用。因此,我需要添加的是 INotifyPropertyChanged 接口,然后每当发生导致 XElement.Elements() 中的数据发生更改的操作时调用 NotifyPropertyChanged() 例程。即,它们是 XElement.Add() 和 XElement.Remove() 例程。还有其他几个,但我只讨论这两个。

这些例程不可重写,但可以使用“new”关键字隐藏它们。这是这些例程的新实现。

public new void Remove()
{
    XElement parent = this.Parent;
    base.Remove();

    if ((parent != null) && (parent.GetType() == typeof(TreeElement)))
    {
    //need to tell parent that they are losing an element
    ((TreeElement)parent).NotifyPropertyChanged("Elements");
    }
}


public new void Add(object Content)
{
    base.Add(Content);
    NotifyPropertyChanged("Elements");
}

正如您所看到的,即使 .Elements() 不是属性,NotifyPropertyChanged("Elements") 方法也可以很好地通知我的绑定 'ItemsSource="{Binding Path=Elements}"'。所以现在当我使用 .Add() 或 .Remove() 更新后面的代码时,我的树会自动更新。

Ok, I have a solution to my own problem. I'm not sure why I thought this would originally work without having to do anything special, but that seems to not be the case.

To clarify the problem a little more, I was not using the the XElement object as is, I had it wrapped by another class so I could add a few more features to it. This was good though because it turns out I needed the INotifyPropertyChanged interface and to override a few methods in order to get the behavior I wanted. My actual class header looks like this.

public class TreeElement : XElement, INotifyPropertyChanged
{
   ...
}

Since my TreeView was binding on the XElement.Elements() routine, it was not receiving notifications when I added or removed elements. The reason why is because XElement.Elements() is NOT a dependency property. Its a routine. I knew this ahead of time but for some reason I was stubborn and still thought it was going to work. So what I needed to add was the INotifyPropertyChanged interface, and then invoke the NotifyPropertyChanged() routine whenever operations occurred that would cause the data from XElement.Elements() to be changed. Namely, they XElement.Add() and XElement.Remove() routine. There are several more but I'll just talk about these two.

These routines are not overridable, but they can be hidden using the "new" key word. Here is the new implementation for those routines.

public new void Remove()
{
    XElement parent = this.Parent;
    base.Remove();

    if ((parent != null) && (parent.GetType() == typeof(TreeElement)))
    {
    //need to tell parent that they are losing an element
    ((TreeElement)parent).NotifyPropertyChanged("Elements");
    }
}


public new void Add(object Content)
{
    base.Add(Content);
    NotifyPropertyChanged("Elements");
}

As you can see, even though .Elements() is not a property the NotifyPropertyChanged("Elements") method works just fine at notifying my binding 'ItemsSource="{Binding Path=Elements}"'. So now when I update in the code behind using .Add() or .Remove() my tree auto updates.

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