コードを使用して、ツリービューアイテムの結合を更新しますか? (XAML / WPF)
-
13-09-2019 - |
質問
私は、そのTreeView
私が持っているモデルに設定されているItemsSource
を持っています。 3つのレベルの深さは、その状態が変化すると、ではなく、各段階(非常に長い事業)を見ると、ビューモデルを書くことができ、私はちょうどこの使用してコードを更新したいオブジェクトです。
だから、基本的に私は私のモデルの更新後に解雇されたイベントを持って、私はこのデータのビットに関連TreeViewItem
を見つけ、それをキャッチ。私の問題は、今私は、新しい値を反映するために、それに結合するのを更新する方法については考えているです!
誰が助けることはできますか?
私はこれがベストプラクティスではありません知っているが、私は本当にただ一つのことを更新するためのコードの膨大な量を書いて時間を無駄にしたくない。
のおかげで クリス
解決
この例では、動作します。それは、番号子供(A.1、B.1、など)を持つ親項目A、B、およびCを有する単純な2レベルの階層ツリービューを示します。名前の変更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のを実装し、それはときに値が変更PropertyChangedイベントを発生さだろう。それがないので、実際には、あなたがメモリリークを発生していないことに注意する必要があります:<のhref = "http://blogs.msdn.com/jgoldb/archive/2008/02/04/finding-memory -leaksインWPFベースの-applications.aspx」のrel = "nofollowをnoreferrer"> WPFアプリケーションの中でメモリリークを発見ます。
他のヒント
あなたは関連するクラスにINotifyPropertyChangedのを実装することが容易ではないでしょうか?
あなたはUpdateSource
とUpdateTarget
方法を見てする必要があるかもしれませんのような音ます。
私はあなたが実際に階層データ構造にツリービューのItemSource
を拘束したら、これは動作します全くわからないんだけど、私は調査を開始する場所、それはですが。