Je tente de créer un TreeView dans WPF qui est lié à une CollectionViewSource. Je crée des groupes dans CollectionViewSource et ai l'installation HierarchicalDataTemplate dans le XAML pour afficher le TreeView correctement.WPF TreeView Dynamic Grouping
Dans mon ViewModel j'ai une méthode pour modifier le regroupement de la CollectionViewSource et tout semble bien fonctionner. Le seul problème que j'ai est d'afficher le CollectionViewSource sans aucun groupement.
Est-ce que quelqu'un sait comment concevoir le modèle pour prendre en charge un scénario dans lequel CollectionViewSource ne possède aucun regroupement, mais peut également accueillir une CollectionViewSource avec des regroupements?
Mise à jour J'ai créé un exemple de code pour mieux décrire ce que je fais. Le DataTemplateSelector fonctionne lorsque l'application démarre mais je n'arrive pas à comprendre comment redéclencher le sélecteur DataTemplate lorsque l'utilisateur sélectionne une option de regroupement différente dans la liste déroulante. Ci-dessous mon exemple de code
<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>
et le code derrière
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;
}
}
}
}
Pas trop d'aide, mais je vais modifier la question initiale pour inclure un exemple de code. – Amit