everyone.
I want to create a ListView that lists items from the Orders class. The list should be grouped by Process.
When I create it as a simple ListView it works fine. I created it following this guide.
Now I don't just want the items to be displayed as list items, but to display them as tiles. The tiles are shown to me. However, in the header no longer the process step according to which is grouped. I don't get an error message either.
Can anyone show me how to do it right?
Many thanks in advance.
MyClass "ORDER":
namespace VersuchBindungDataTemplate
{
public class Order
{
public string Process { get; set; }
public string Auftrag { get; set; }
public string Material { get; set; }
public string Type { get; set; }
}
}
**My Code behind:**
public partial class MainWindow : Window
{
ObservableCollection<Order> items = new();
public MainWindow()
{
InitializeComponent();
items.Add(new Order() { Process = "Schweißen", Auftrag = "5121511", Material = "71231521", Type = "SD5" });
items.Add(new Order() { Process = "Elmo", Auftrag = "5121513", Material = "71231523", Type = "SD7" });
items.Add(new Order() { Process = "Öl füllen", Auftrag = "5121514", Material = "71231526", Type = "SD5" });
items.Add(new Order() { Process = "Schweißen", Auftrag = "5121511", Material = "71231521", Type = "SD5" });
items.Add(new Order() { Process = "Schweißen", Auftrag = "5121513", Material = "71231523", Type = "SD7" });
items.Add(new Order() { Process = "Öl füllen", Auftrag = "5121514", Material = "71231526", Type = "SD5" });
items.Add(new Order() { Process = "Schweißen", Auftrag = "5121511", Material = "71231521", Type = "SD5" });
items.Add(new Order() { Process = "Elmo", Auftrag = "5121513", Material = "71231523", Type = "SD7" });
items.Add(new Order() { Process = "Öl füllen", Auftrag = "5121514", Material = "71231526", Type = "SD5" });
lvOrders.ItemsSource = items;
CollectionView view = (CollectionView)CollectionViewSource.GetDefaultView(lvOrders.ItemsSource);
PropertyGroupDescription groupDescription = new PropertyGroupDescription("Process");
view.GroupDescriptions.Add(groupDescription);
view.Filter = UserFilter;
}
private bool UserFilter(object item)
{
if (string.IsNullOrEmpty(txtFilter.Text))
{
return true;
}
else
{
return (item as Order).Auftrag.Contains(txtFilter.Text, StringComparison.OrdinalIgnoreCase);
}
}
private void txtFilter_TextChanged(object sender, TextChangedEventArgs e)
{
CollectionViewSource.GetDefaultView(lvOrders.ItemsSource).Refresh();
}
}
}
My XAML:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="50"/>
<RowDefinition Height="150*"/>
</Grid.RowDefinitions>
<TextBox Grid.Row="0" Name="txtFilter" TextChanged="txtFilter_TextChanged" Height="20" Margin="10" />
<ListView Margin="10" Name="lvOrders" Grid.Row="1" ItemTemplate="{StaticResource ExplorerView}" SelectionMode="Single" ScrollViewer.HorizontalScrollBarVisibility="Disabled">
<ListView.Resources>
<c:Order x:Key="Orders" />
</ListView.Resources>
<ListView.DataContext>
<Binding Source="{StaticResource Orders}"/>
</ListView.DataContext>
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Margin="10" />
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.GroupStyle>
<GroupStyle>
<GroupStyle.ContainerStyle>
<Style TargetType="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Expander IsExpanded="True">
<Expander.Header>
<StackPanel Orientation="Horizontal" Width="800">
<TextBlock Text="{Binding Process}" FontWeight="Bold" Foreground="Black" FontSize="24"/>
<TextBlock Text="Aufträge: " FontSize="22" Foreground="Silver" FontStyle="Italic"/>
<TextBlock Text="{Binding ItemCount}" FontSize="22" Foreground="Green" FontWeight="Bold" FontStyle="Italic"/>
</StackPanel>
</Expander.Header>
<ItemsPresenter />
</Expander>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<TextBlock FontWeight="Bold" FontSize="14" Text="{Binding Process}"/>
</DataTemplate>
</GroupStyle.HeaderTemplate>
</GroupStyle>
</ListView.GroupStyle>
</ListView>
</Grid>
My AppResources:
<Application.Resources>
<ResourceDictionary>
<!-- Tile-style layout-->
<DataTemplate x:Key="ExplorerView">
<Border BorderThickness="3" BorderBrush="LightGray">
<StackPanel Background="LightGray" Width="150" Height="150">
<TextBlock Text="{Binding Process}" FontSize="9" HorizontalAlignment="Left" />
<TextBlock Text="{Binding Auftrag}" FontSize="18" HorizontalAlignment="Left" />
<TextBlock Text="{Binding Material}" FontSize="9" HorizontalAlignment="Left" />
<TextBlock Text="{Binding Type}" FontSize="9" HorizontalAlignment="Left" />
</StackPanel>
</Border>
</DataTemplate>
</ResourceDictionary>
</Application.Resources>
Your GroupStyle has no knowledge of the properties in your Orders
class, so it doesn't understand what Process
is. Take a look at ItemCount
, where did that come from? Not from the Orders
class.
Luckily, your GroupStyle knows what it is grouped by, and it has a Name
, which is what you bound the Process
property to in your code-behind.
So it should be an easy fix where you just replace your {Binding Process}
with {Binding Name}
inside of your GroupStyle.
<StackPanel Orientation="Horizontal" Width="800">
<TextBlock Text="{Binding Name}" FontWeight="Bold" Foreground="Black" FontSize="24"/>
<TextBlock Text="Aufträge: " FontSize="22" Foreground="Silver" FontStyle="Italic"/>
<TextBlock Text="{Binding ItemCount}" FontSize="22" Foreground="Green" FontWeight="Bold" FontStyle="Italic"/>
</StackPanel>
Your output will now look like this: