Reputation: 499
I've got a DataGrid in WPF with groups based on a property, but I wan't to have some groups present even when there is no corresponding item.
My code is base on that but with the DataGrid it doesn't work.
<Window
x:Class="EmptyGroups.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Servers by cluster"
WindowStartupLocation="CenterScreen">
<DockPanel>
<WrapPanel DockPanel.Dock="Top" Background="BlanchedAlmond">
<Label Content="Cluster name:" Margin="10"/>
<TextBox x:Name="NewClusterName" Text="type new cluster name here" MinWidth="50" BorderThickness="1" Margin="10"/>
<Button Content="Add cluster" Click="AddNewCluster_Click" Margin="10"/>
</WrapPanel>
<ListView x:Name="ServersList">
<ListView.GroupStyle>
<GroupStyle HidesIfEmpty="False">
<GroupStyle.ContainerStyle>
<Style TargetType="GroupItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="GroupItem">
<Expander IsExpanded="True">
<Expander.Header>
<TextBlock TextWrapping="Wrap" Margin="0,10,0,5" >
<Bold><TextBlock Text="{Binding Name}"/></Bold> (<TextBlock Text="{Binding ItemCount}"/> servers)
</TextBlock>
</Expander.Header>
<ItemsPresenter/>
</Expander>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
</GroupStyle>
</ListView.GroupStyle>
<ListView.View>
<GridView>
<GridViewColumn Header="Server" DisplayMemberBinding="{Binding Name}"/>
<GridViewColumn Header="Cluster" DisplayMemberBinding="{Binding Cluster.Name}"/>
</GridView>
</ListView.View>
</ListView>
<DataGrid Name="ServersGrid" AutoGenerateColumns="False" IsReadOnly="True">
<DataGrid.GroupStyle>
<GroupStyle HidesIfEmpty="False">
<GroupStyle.Panel>
<ItemsPanelTemplate>
<DataGridRowsPresenter/>
</ItemsPanelTemplate>
</GroupStyle.Panel>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<DockPanel>
<TextBlock Text="" Width="20" />
<TextBlock Text="{Binding Path=Name}"/>
</DockPanel>
</DataTemplate>
</GroupStyle.HeaderTemplate>
</GroupStyle>
</DataGrid.GroupStyle>
<DataGrid.Columns>
<DataGridTextColumn Header="ServerGrid" Binding="{Binding Name}" />
<DataGridTextColumn Header="ClusterGrid" Binding="{Binding Cluster.Name}"/>
</DataGrid.Columns>
</DataGrid>
</DockPanel>
And Windows1.xaml.cs :
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");
// this foreach must at least add clusters that can't be
// derived from items - i.e. groups with no items in them
foreach (var cluster in clusters)
groupDescription.GroupNames.Add(cluster.Name);
collectionView.GroupDescriptions.Add(groupDescription);
ServersList.ItemsSource = collectionView;
ServersGrid.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; }
}
}
After 6 add the DataGrid stop to show all the empty groups. Thanks.
Upvotes: 3
Views: 1845
Reputation: 499
Following a question, I answer it myself. Due to a bug in WPF DataGrid there can't be more groups than items, so we add a ghost item for every group present or not and set their Visibility as Collapsed.
Upvotes: 1