Aggiornamento legame di TreeViewItem usando il codice? (XAML / WPF)
-
13-09-2019 - |
Domanda
Ho un TreeView
cui ItemsSource
è impostato su un modello che ho. 3 livelli di profondità è un oggetto il cui stato può cambiare e, piuttosto che scrivere un View e ViewModel per ogni fase (molto lunga business) Ho voluto aggiornare solo questo codice usando.
Quindi, fondamentalmente ho un evento che viene generato una volta i miei aggiornamenti modello, ho prenderlo poi trovare la TreeViewItem
associata a questo po 'di dati. Il mio problema ora è che non ho idea su come aggiornare il legame su di esso per riflettere il nuovo valore!
Chiunque può aiutare?
So che questo non è delle migliori pratiche, ma davvero non voglio avere a sprecare tempo a scrivere una massiccia quantità di codice per aggiornare solo una cosa.
Grazie Chris
Soluzione
Questo esempio funziona, anche se è solo due (non 3) livelli di profondità. Essa mostra una semplice vista ad albero gerarchico 2 livelli con elementi padre A, B, e C, con bambini numerati (A.1, B.1, ecc). Quando il pulsante Rename B.1 viene cliccato, si rinomina B.1 a "Sylvia".
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>
Questo è un hack, ma ri-valuta il DataTemplate ogni volta che si tratta di modifiche di proprietà ItemsSource.
Idealmente, si dovrebbe implementare INotifyPropertyChanged del modello di classe di oggetti che questo TreeViewItem è destinato a, e lo hanno genera l'evento PropertyChanged quando questo valore cambia. In realtà, si dovrebbe fare attenzione a che non si incorrere in una perdita di memoria, perché non è così: Trovare memoria-perdite in applicazioni WPF .
Altri suggerimenti
Sei sicuro che non sarebbe stato più facile da implementare INotifyPropertyChanged sulla relativa classe?
Suona come potrebbe essere necessario dare un'occhiata a metodi UpdateSource
e UpdateTarget
.
di riferimento MSDN per UpdateSource
Anche se non sono del tutto sicuro che questo funziona quando hai effettivamente tenuti ItemSource
del controllo TreeView a una struttura di dati gerarchica, ma è dove vorrei iniziare a indagare.