Проблема с обновлениями TreeView с привязанными к данным XML-данными через XElement - PullRequest
1 голос
/ 22 сентября 2011

У меня есть TreeView, реализованный в WPF, который связан с некоторыми данными XML через класс XElement.При загрузке файла 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 () изменились, и экран обновился автоматически.В любом случае, на этот раз не работает.Кто-нибудь знает почему?

1 Ответ

0 голосов
/ 23 сентября 2011

Хорошо, у меня есть решение моей проблемы.Я не уверен, почему я думал, что изначально это будет работать без необходимости делать что-то особенное, но, похоже, это не так.

Чтобы прояснить проблему немного больше, я не использовал объект XElementкак есть, у меня был другой класс, чтобы я мог добавить к нему еще несколько функций.Это было хорошо, хотя, как оказалось, мне нужен интерфейс INotifyPropertyChanged и переопределить несколько методов, чтобы получить желаемое поведение.Мой фактический заголовок класса выглядит следующим образом.

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

Поскольку мой TreeView связывался с подпрограммой XElement.Elements (), он не получал уведомлений при добавлении или удалении элементов.Причина в том, что XElement.Elements () НЕ является свойством зависимости.Это рутина.Я знал это заранее, но по какой-то причине я был упрям ​​и все еще думал, что это сработает.Поэтому мне нужно было добавить интерфейс INotifyPropertyChanged, а затем вызывать процедуру NotifyPropertyChanged () всякий раз, когда происходили операции, которые приводили к изменению данных из XElement.Elements ().А именно они XElement.Add () и XElement.Remove () подпрограммы.Есть еще несколько, но я просто расскажу об этих двух.

Эти подпрограммы не могут быть переопределены, но они могут быть скрыты с помощью «нового» ключевого слова.Вот новая реализация для этих подпрограмм.

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 (), мое дерево автоматически обновляется.

...