我不是真的建議,但我會解決你有 XAML
<StackPanel x:Name="root">
<StackPanel.DataContext>
<vm:MainWindowViewModel></vm:MainWindowViewModel>
</StackPanel.DataContext>
<Button Command="{Binding AddRoot}">Add</Button>
<TreeView Height="400">
<TreeView.Resources >
<Style TargetType="{x:Type TreeViewItem}">
<Setter Property="IsExpanded" Value="True">
</Setter>
</Style>
<vm:HierarchicalDataConverter x:Key="HierarchicalDataConverter"/>
<HierarchicalDataTemplate x:Key="ParentEntityTemplate" DataType="{x:Type vm:ParentEntity}" >
<HierarchicalDataTemplate.ItemsSource>
<MultiBinding Converter="{StaticResource HierarchicalDataConverter}" Mode="TwoWay">
<Binding Mode="OneTime"></Binding>
<Binding Path="DataContext.Items" ElementName="root" ></Binding>
<Binding Path="DataContext.Items.Count" ElementName="root" ></Binding>
</MultiBinding>
</HierarchicalDataTemplate.ItemsSource>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{ Binding Name }"></TextBlock>
<Button Command="{Binding DataContext.AddLeafe, ElementName=root}" CommandParameter="{Binding}">Add item</Button>
</StackPanel>
</HierarchicalDataTemplate>
<DataTemplate x:Key="ChildEntityTemplate" DataType="{x:Type vm:ChildEntity}">
<TextBlock Text="{Binding Name}"></TextBlock>
</DataTemplate>
</TreeView.Resources>
<TreeView.ItemsSource>
<Binding Path="RootItems"/>
</TreeView.ItemsSource>
<TreeView.ItemTemplateSelector>
<vm:ItemTemplateSelector>
</vm:ItemTemplateSelector>
</TreeView.ItemTemplateSelector>
</TreeView>
</StackPanel>
VM命名空間
public class MainWindowViewModel : BindableBase
{
public ObservableCollection<object> Items { get; } =
new ObservableCollection<object>(new List<object>(new List<object>
{
new ParentEntity { UID = 1, Name = "Groop1" },
new ChildEntity { ParentUID = 1, Name = "Item1" },
new ParentEntity { UID = 2, Name = "Groop2" },
new ChildEntity { ParentUID = 2, Name = "Item1" },
new ChildEntity { ParentUID = 2, Name = "Item2" },
new ChildEntity { ParentUID = 2, Name = "Item3" }
}));
public CollectionView RootItems { get; }
int count = 2;
public DelegateCommand AddRoot { get; }
public DelegateCommand<ParentEntity> AddLeafe { get; }
public MainWindowViewModel()
{
RootItems = new ListCollectionView(Items) { Filter = (item) => item is ParentEntity };
AddRoot = new DelegateCommand(() =>
{
Items.Add(new ParentEntity { UID = ++count ,Name= "Group"+count});
});
AddLeafe = new DelegateCommand<ParentEntity>((pe) =>
{
Items.Add(new ChildEntity { ParentUID = pe.UID, Name = "Item" + count });
});
}
}
public class ParentEntity
{
public int UID { get; set; }
public string Name { get; set; }
}
public class ChildEntity
{
public int ParentUID { get; set; }
public string Name { get; set; }
public int Value { get; set; }
}
public class ItemTemplateSelector : DataTemplateSelector
{
public override DataTemplate
SelectTemplate(object item, DependencyObject container)
{
FrameworkElement element = container as FrameworkElement;
if (item is ParentEntity)
{
return element.FindResource("ParentEntityTemplate") as DataTemplate;
}
if (item is ChildEntity)
{
return element.FindResource("ChildEntityTemplate") as DataTemplate;
}
return null;
}
}
public class HierarchicalDataConverter : IMultiValueConverter
{
public object Convert(object[] value, Type targetType, object parameter, CultureInfo culture)
{
if (value[0] != null)
{
ParentEntity pe = value[0] as ParentEntity;
var items = value[1] as IEnumerable<object>;
return items.Where((item) => item is ChildEntity && (item as ChildEntity).ParentUID == pe.UID);
}
return null;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
的問題,這樣的問題是,它會重新創建所有的子節點
您是否考慮將實體包裝在提供您在問題的第一部分中描述的結構的對象中? – vkluge
是的,這是第一個想法,但我不確定這是否正確。 – Feofilakt
您可以嘗試使用IValueConverter調用一個方法,該方法將相應的子對象返回給父級,請參閱[這裏](http://stackoverflow.com/a/844946/4189791),但是這是明確的不是「正確的」做法。 – vkluge