WPF C# 修改 ListView 组 Header - 数据绑定
WPF C# Modify ListView Group Header - Data Binding
大家。
我想创建一个 ListView 来列出订单 class 中的项目。该列表应按进程分组。
当我将它创建为一个简单的 ListView 时,它工作正常。 I created it following this guide.
现在我不只是希望将项目显示为列表项,而是将它们显示为图块。
瓷砖是给我看的。但是,在 header 中不再根据哪个过程步骤进行分组。我也没有收到错误消息。
Screenshot
谁能告诉我正确的做法?
非常感谢。
MyClass“订单”:
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();
}
}
}
我的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>
我的应用资源:
<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>
您的 GroupStyle 不了解 Orders
class 中的属性,因此它不了解 Process
是什么。看看ItemCount
,那是哪里来的?不是来自 Orders
class.
幸运的是,您的 GroupStyle 知道它是按什么分组的,并且它有一个 Name
,这就是您在 code-behind 中将 Process
属性 绑定到的内容.
因此,只需将 GroupStyle 中的 {Binding Process}
替换为 {Binding Name}
即可轻松修复。
<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>
您的输出现在将如下所示:
大家。
我想创建一个 ListView 来列出订单 class 中的项目。该列表应按进程分组。
当我将它创建为一个简单的 ListView 时,它工作正常。 I created it following this guide.
现在我不只是希望将项目显示为列表项,而是将它们显示为图块。 瓷砖是给我看的。但是,在 header 中不再根据哪个过程步骤进行分组。我也没有收到错误消息。
Screenshot
谁能告诉我正确的做法?
非常感谢。
MyClass“订单”:
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();
}
}
}
我的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>
我的应用资源:
<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>
您的 GroupStyle 不了解 Orders
class 中的属性,因此它不了解 Process
是什么。看看ItemCount
,那是哪里来的?不是来自 Orders
class.
幸运的是,您的 GroupStyle 知道它是按什么分组的,并且它有一个 Name
,这就是您在 code-behind 中将 Process
属性 绑定到的内容.
因此,只需将 GroupStyle 中的 {Binding Process}
替换为 {Binding Name}
即可轻松修复。
<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>
您的输出现在将如下所示: