В классе есть несколько наборов данных (элементы в коллекции имеют подэлементы). Вопрос состоит из двух частей.
Вопрос
Во-первых, как объединить несколько коллекций под одним элементом дерева? Во-вторых, как создать заголовок для коллекции?
Данные должны быть представлены следующим образом:
MasterItem
-SubItemsT1GeneratedHeader
--SubItem1
---SubVal
---SubVal
--SubItem1
---SubVal
---SubVal
-SubItem2
-SubItem2
Объекты
public class MasterItem : BaseItem {
public ObservableCollection<SubItem1> subItem1s { get; set; }
public ObservableCollection<SubItem2> subItem2s { get; set; } }
public class SubItem2 : BaseItem { }
public class SubItem1 : BaseItem {
public ObservableCollection<SubVal> subVals { get; set; } }
public class SubVal : BaseItem { }
public class BaseItem : INotifyPropertyChanged {
public BaseItem() { IsExpanded = true; }
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged([CallerMemberName] String propertyName = "") {
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); }
public string Name => this.GetType().Name;
public bool _isExpanded;
public bool IsExpanded {
get { return this._isExpanded; }
set {
if (value != this._isExpanded){
this._isExpanded = value;
NotifyPropertyChanged();
} }
}
}
Код позади
InitializeComponent();
var mItem1 = new MasterItem()
{
//needs to have label Type1SubItems
subItem1s = new ObservableCollection<SubItem1>() {
new SubItem1() {
subVals = new ObservableCollection<SubVal>() { new SubVal(), new SubVal() } },
new SubItem1() {
subVals = new ObservableCollection<SubVal>() { new SubVal(), new SubVal() } } },
//needs to have just name
subItem2s = new ObservableCollection<SubItem2>() {
new SubItem2(), new SubItem2() } };
var items = new ObservableCollection<MasterItem>() { mItem1 };
tree1.ItemsSource = items;
XAML (вывод не по желанию)
<TreeView Name="tree1">
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type local:MasterItem}" ItemsSource="{Binding subItem1s}">
<TextBlock Text="{Binding Name}"/>
</HierarchicalDataTemplate>
<HierarchicalDataTemplate DataType="{x:Type local:SubItem1}" ItemsSource="{Binding subVals}">
<TextBlock Text="{Binding Name}"/>
</HierarchicalDataTemplate>
</TreeView.Resources>
<TreeView.ItemContainerStyle>
<Style TargetType="TreeViewItem">
<Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}" />
</Style>
</TreeView.ItemContainerStyle>
</TreeView>
Одним из возможных решений было бы добавление промежуточного класса ксодержит коллекцию коллекций SubItem1 (т.е. subItems1). Затем MasterItem будет содержать коллекцию промежуточных классов (фактически только с одним элементом). Свойство Name промежуточного класса будет «SubItemsT1GeneratedHeader». Коллекция промежуточных классов и subItems2s может быть помещена в CompositeCollection, чтобы обеспечить только один ItemsSource для HierarchicalDataTemplate. Тогда я мог бы использовать предоставленное решение здесь . Но как можно дольше я бы хотел избежать изменений в структуре данных.
Другое возможное решение описано здесь . Это выглядит так, как я хочу, но мне нужно добавить контекстное меню и свойства к сгенерированному заголовку в xaml.
Еще одно ограничение решения состоит в том, что все элементы (включая заголовок) должны бытьвозможно расширение из кода с помощью свойства IsExpanded.