Ich versuche, ein TreeView in WPF zu erstellen, das an eine CollectionViewSource gebunden ist. Ich erstelle Gruppen in der CollectionViewSource und habe das HierarchicalDataTemplate-Setup in XAML, um das TreeView ordnungsgemäß anzuzeigen.WPF-TreeView-dynamische Gruppierung
In meinem ViewModel habe ich eine Methode, um die Gruppierung der CollectionViewSource zu ändern und alles scheint gut zu funktionieren. Das einzige Problem, das ich habe, zeigt die CollectionViewSource ohne irgendeine Gruppierung an.
Kann jemand die Vorlage entwerfen, um ein Szenario unterzubringen, in dem die CollectionViewSource keine Gruppierungen hat, aber auch eine CollectionViewSource mit Gruppierungen aufnehmen kann?
Aktualisieren Ich habe einige Beispielcode erstellt, um besser zu beschreiben, was ich mache. Der DataTemplateSelector funktioniert, wenn die Anwendung gestartet wird, aber ich kann nicht herausfinden, wie der DataTemplate-Selektor erneut ausgelöst wird, wenn der Benutzer eine andere Gruppierungsoption aus der Combobox auswählt. Unten ist mein Beispielcode
<Window
x:Class="TreeViewGroupTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:TreeViewGroupTest"
Title="WindowsApplication1"
Height="Auto" Width="300">
<Window.Resources>
<local:SchoolTemplateSelector x:Key="schoolTemplateSelector" />
<HierarchicalDataTemplate x:Key="BasicList" ItemsSource="{Binding TeachersBy.Source}">
<StackPanel>
<TextBlock Text="{Binding Name}" />
<ComboBox SelectionChanged="ComboBox_SelectionChanged" ItemsSource="{Binding GroupByList}" />
</StackPanel>
<HierarchicalDataTemplate.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Last}" />
</DataTemplate>
</HierarchicalDataTemplate.ItemTemplate>
</HierarchicalDataTemplate>
<HierarchicalDataTemplate x:Key="GroupList" ItemsSource="{Binding TeachersBy.View.Groups}">
<StackPanel>
<TextBlock Text="{Binding Name}" />
<ComboBox SelectionChanged="ComboBox_SelectionChanged" ItemsSource="{Binding GroupByList}" />
</StackPanel>
<HierarchicalDataTemplate.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Items}">
<TextBlock Text="{Binding Name}" />
<HierarchicalDataTemplate.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Last}" />
</DataTemplate>
</HierarchicalDataTemplate.ItemTemplate>
</HierarchicalDataTemplate>
</HierarchicalDataTemplate.ItemTemplate>
</HierarchicalDataTemplate>
</Window.Resources>
<StackPanel>
<TreeView ItemsSource="{Binding Schools}" ItemTemplateSelector="{Binding schoolTemplateSelector}" />
</StackPanel>
und der Code hinter
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Collections.ObjectModel;
namespace TreeViewGroupTest
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public ObservableCollection<School> Schools { get; set; }
public SchoolTemplateSelector schoolTemplateSelector { get; set; }
private string group = "Subject";
public string GroupByChoice { get; set; }
public MainWindow()
{
InitializeComponent();
GroupByChoice = "Subject";
Schools = new ObservableCollection<School> {
new School
{
Name = "Apple",
Teachers = new ObservableCollection<Teacher> {
new Teacher { Last = "Alpha", Subject = "Math" , Grade = "9th" },
new Teacher { Last = "Beta", Subject = "English" , Grade = "9th" },
new Teacher { Last = "Charlie", Subject = "Math" , Grade = "9th" },
new Teacher { Last = "Delta", Subject = "English" , Grade = "10th" },
new Teacher { Last = "Echo", Subject = "Math" , Grade = "10th" },
new Teacher { Last = "Foxtrot", Subject = "English" , Grade = "10th" },
}
},
new School
{
Name = "Microsoft",
Teachers = new ObservableCollection<Teacher> {
new Teacher { Last = "Alpha", Subject = "Math" , Grade = "9th" },
new Teacher { Last = "Beta", Subject = "English" , Grade = "9th" },
new Teacher { Last = "Charlie", Subject = "Math" , Grade = "9th" },
new Teacher { Last = "Delta", Subject = "English" , Grade = "10th" },
new Teacher { Last = "Echo", Subject = "Math" , Grade = "10th" },
new Teacher { Last = "Foxtrot", Subject = "English" , Grade = "10th" },
}
},
};
Schools[0].SetTeacher(); ;
Schools[1].GroupBy("Subject");
Schools[1].TeachersBy.View.Refresh();
this.DataContext = this;
schoolTemplateSelector = new SchoolTemplateSelector();
}
private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
string prop = e.AddedItems[0].ToString();
if (prop != "None")
{
foreach (School s in Schools)
{
s.GroupBy(prop);
}
}
else
{
foreach (School s in Schools)
{
s.TeachersBy.GroupDescriptions.Clear();
}
}
//The DataTemplateSelector should fire now...
}
}
public class School
{
public string Name { get; set; }
public ObservableCollection<Teacher> Teachers { get; set; }
public CollectionViewSource TeachersBy { get; set; }
public ObservableCollection<String> GroupByList { get; set; }
public School()
{
Teachers = new ObservableCollection<Teacher>();
TeachersBy = new CollectionViewSource();
GroupByList = new ObservableCollection<string> {
"None", "Subject", "Grade"
};
}
public void SetTeacher()
{
TeachersBy.Source = Teachers;
}
public void GroupBy(string propertyName)
{
TeachersBy.Source = Teachers;
TeachersBy.GroupDescriptions.Clear();
TeachersBy.GroupDescriptions.Add(new PropertyGroupDescription(propertyName));
TeachersBy.View.Refresh();
}
}
public class Teacher
{
public string Last { get; set; }
public string Subject { get; set; }
public string Grade { get; set; }
public Teacher() { }
}
public class SchoolTemplateSelector : DataTemplateSelector
{
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
FrameworkElement element = container as FrameworkElement;
if (item is School && (item as School).TeachersBy.GroupDescriptions.Count > 0)
{
return
element.FindResource("GroupList")
as DataTemplate;
}
else
{
return
element.FindResource("BasicList")
as DataTemplate;
}
}
}
}
War nicht zu viel Hilfe, aber ich werde die ursprüngliche Frage bearbeiten, um Beispielcode einzuschließen. – Amit