Обновить привязку TreeViewItem с помощью кода?(XAML / WPF)
-
13-09-2019 - |
Вопрос
У меня есть TreeView
чей ItemsSource
настроен на Модель, которая у меня есть.глубина 3 уровня - это объект, состояние которого может меняться, и вместо того, чтобы писать View и ViewModel для каждого этапа (очень длительный бизнес) Я хотел просто обновить это с помощью кода.
Итак, в основном у меня есть событие, которое запускается после обновления моей модели, я перехватываю его, а затем нахожу TreeViewItem
связанный с этим битом данных.Моя проблема сейчас в том, что я понятия не имею, как обновить привязку к нему, чтобы отразить новое значение!
Кто-нибудь может помочь?
Я знаю, что это не лучшая практика, но я действительно не хочу тратить время на написание огромного количества кода, чтобы просто обновить что-то одно.
Спасибо Крис
Решение
Этот пример работает, хотя он имеет глубину всего два (не 3) уровня.Он показывает простое двухуровневое иерархическое древовидное представление с родительскими элементами A, B и C и пронумерованными дочерними элементами (A.1, B.1 и т.д.).Когда нажимается кнопка Переименовать B.1, она переименовывает B.1 в "Сильвия".
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
namespace UpdateVanillaBindingValue
{
/// <summary>
/// Interaction logic for Window1.xaml
/// </summary>
public partial class Window1 : Window
{
private DataClass _data;
public Window1()
{
InitializeComponent();
var data = CreateData();
DataContext = _data = data;
}
private DataClass CreateData()
{
return new DataClass
{
Parents=new List<Parent>
{
new Parent{Name="A",Children=new List<Child>{new Child{Name="A.0"},new Child{Name="A.1"}}},
new Parent{Name="B",Children=new List<Child>{new Child{Name="B.0"},new Child{Name="B.1"},new Child{Name="B.2"}}},
new Parent{Name="C",Children=new List<Child>{new Child{Name="C.0"},new Child{Name="C.1"}}}
}
};
}
private void Rename_Click(object sender, RoutedEventArgs e)
{
var parentB = _data.Parents[1];
var parentBItem = TheTree.ItemContainerGenerator.ContainerFromItem(parentB) as TreeViewItem;
parentB.Children[1].Name = "Sylvia";
var parentBItemsSource = parentBItem.ItemsSource;
parentBItem.ItemsSource = null;
parentBItem.ItemsSource = parentBItemsSource;
}
}
public class DataClass
{
public List<Parent> Parents { get; set; }
}
public class Parent
{
public string Name { get; set; }
public List<Child> Children { get; set; }
}
public class Child
{
public string Name { get; set; }
}
}
<Window x:Class="UpdateVanillaBindingValue.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Grid>
<Grid.Resources>
<DataTemplate x:Key="ChildTemplate">
<TextBlock Margin="50,0,0,0" Text="{Binding Name}" />
</DataTemplate>
<HierarchicalDataTemplate x:Key="ParentTemplate" ItemsSource="{Binding Children}" ItemTemplate="{StaticResource ChildTemplate}">
<TextBlock Text="{Binding Name}" />
</HierarchicalDataTemplate>
</Grid.Resources>
<TreeView x:Name="TheTree" ItemsSource="{Binding Parents}" ItemTemplate="{StaticResource ParentTemplate}" />
<Button VerticalAlignment="Bottom" HorizontalAlignment="Center" Content="Rename B.1" Click="Rename_Click" />
</Grid>
</Window>
Это взлом, но он переоценивает DataTemplate каждый раз, когда изменяется его свойство ItemsSource.
В идеале вы должны реализовать INotifyPropertyChanged в вашем классе объектов модели, к которому привязан этот TreeViewItem , и заставить его запускать событие PropertyChanged при изменении этого значения.На самом деле, вы должны быть осторожны, чтобы не допустить утечки памяти, потому что это не: Поиск утечек памяти в приложениях WPF.
Другие советы
Вы уверены, что не было бы проще реализовать INotifyPropertyChanged в соответствующем классе?
Похоже, вам, возможно, стоит взглянуть на UpdateSource
и UpdateTarget
методы.
Ссылка на MSDN для источника обновлений
Хотя я не совсем уверен, что это сработает, когда вы действительно свяжете TreeView с ItemSource
к иерархической структуре данных, но именно с этого я бы начал расследование.