Introduction
WPF has a ListView
control which uses the CollectionView
class for sorting and grouping. MSDN gives an example of how to use this class to derive groups from the items list. However, there is no example of how to add empty groups, which can't be derived from the items list.
Consider an example scenario - the user must be presented with a servers list, grouped by clusters. The ListView
can be used to display the servers (primary information) and grouped by clusters (secondary information). The user must be able to add a new cluster to populate it with servers. After a new cluster is added, it is not displayed because there is no server referencing the new cluster.
Using the code
You can add groups using the GroupDescription.GroupNames
property.
using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Data;
namespace EmptyGroups
{
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
var clusters = new[]
{
new Cluster { Name = "Front end" },
new Cluster { Name = "Middle end" },
new Cluster { Name = "Back end" },
};
var collectionView = new ListCollectionView(new[]
{
new Server { Cluster = clusters[0], Name = "webshop1" },
new Server { Cluster = clusters[0], Name = "webshop2" },
new Server { Cluster = clusters[0], Name = "webshop3" },
new Server { Cluster = clusters[0], Name = "webshop4" },
new Server { Cluster = clusters[0], Name = "webshop5" },
new Server { Cluster = clusters[0], Name = "webshop6" },
new Server { Cluster = clusters[2], Name = "sql1" },
new Server { Cluster = clusters[2], Name = "sql2" },
});
var groupDescription = new PropertyGroupDescription("Cluster.Name");
foreach (var cluster in clusters)
groupDescription.GroupNames.Add(cluster.Name);
collectionView.GroupDescriptions.Add(groupDescription);
ServersList.ItemsSource = collectionView;
Clusters = groupDescription.GroupNames;
}
readonly ObservableCollection<object> Clusters;
void AddNewCluster_Click(object sender, RoutedEventArgs e)
{
Clusters.Add(NewClusterName.Text);
}
}
class Cluster
{
public string Name { get; set; }
}
class Server
{
public Cluster Cluster { get; set; }
public string Name { get; set; }
}
}