C# WPF Listview按数据组而非行替换行背景
我找不到解决我的问题/想法的方法,我希望有人能帮助我。 在WPF中,我有一个C# WPF Listview按数据组而非行替换行背景,c#,wpf,xaml,listview,C#,Wpf,Xaml,Listview,我找不到解决我的问题/想法的方法,我希望有人能帮助我。 在WPF中,我有一个CollectionViewSource,这取决于IEnumerable。 项目包含姓名、身高、年龄字段。 在Xaml中,ListView的ItemsSource=“{Binding CollectionViewSource.View}” 我知道,Listview有一个AlternationCount属性,可以更改行背景色 但我只想在“年龄”字段数据与上述行的年龄数据不同时更改行背景色 这样,按年龄排序: 只有当年龄数
CollectionViewSource
,这取决于IEnumerable
。
项目
包含姓名、身高、年龄字段。
在Xaml中,ListView的ItemsSource=“{Binding CollectionViewSource.View}”
我知道,Listview
有一个AlternationCount
属性,可以更改行背景色
但我只想在“年龄”字段数据与上述行的年龄数据不同时更改行背景色
这样,按年龄排序:
只有当年龄数据不同时,行背景色才会改变
当我为列表设置另一个排序顺序时,也应该更改交替顺序
在此图片中,列表按名称排序:
但是背景颜色取决于年龄数据
有什么方法可以解决这个问题吗?您可以使用
首先,创建一个IMultivalueConverter
,它将接受您要比较的值,并基于这些值返回当前替换索引:
class ComparisonConverter : IMultiValueConverter
{
private int currentAlternation = 0;
public int AlternationCount { get; set; } = 2;
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
// TODO: exception handling
if (values.Distinct().Count() != 1)
{
if (++currentAlternation >= AlternationCount)
{
currentAlternation = 0;
}
}
return currentAlternation;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
当所有值相等时,此转换器接受多个值并返回一个不变的交替索引;否则,它首先将交替索引更改为下一个索引,然后返回一个新索引
现在,创建一个多重绑定
,它将为样式
提供可选索引值,您可以在其中定义颜色:
<!-- This is an incomplete ListView! Set the View and ItemsSource as required. -->
<ListView>
<ListView.Resources>
<local:ComparisonConverter x:Key="ComparisonConverter"/>
</ListView.Resources>
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Style.Triggers>
<!-- This is the DataTrigger for the alternation index 1 -->
<DataTrigger Value="1">
<DataTrigger.Binding>
<MultiBinding Converter="{StaticResource ComparisonConverter}">
<Binding Path="Age"/>
<Binding Path="Age" RelativeSource="{RelativeSource PreviousData}"/>
</MultiBinding>
</DataTrigger.Binding>
<Setter Property="Background" Value="Red"/>
</DataTrigger>
</Style.Triggers>
<Setter Property="Background" Value="Wheat"/>
</Style>
</ListView.ItemContainerStyle>
</ListView>
因此,在这种样式中,交替索引0的默认颜色是小麦。使用数据触发器
,交替索引1将生成红色
排序顺序的更改将自动反映出来,因为
CollectionViewSource
将重建视图,因此ListView
将使用MultiBinding
为每个项目从头开始创建所有项目。运行此操作并充分享受生活:
XAML:
<Window x:Class="WpfStackOverflow.Window6"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window6" Height="362.03" Width="563.91">
<Window.Resources>
<CollectionViewSource x:Key="CVS" Source="{Binding .}">
<CollectionViewSource.GroupDescriptions>
<PropertyGroupDescription PropertyName="Age"/>
</CollectionViewSource.GroupDescriptions>
</CollectionViewSource>
</Window.Resources>
<Grid>
<ListView x:Name="LstView" ItemsSource="{Binding Source={StaticResource CVS}}">
<ListView.Resources>
<AlternationConverter x:Key="AltCnvKey">
<SolidColorBrush Color="Snow"/>
<SolidColorBrush Color="LightBlue"/>
<SolidColorBrush Color="Orange"/>
</AlternationConverter>
</ListView.Resources>
<ListView.View>
<GridView>
<GridView.Columns>
<GridViewColumn DisplayMemberBinding="{Binding Name}" Header="Name"/>
<GridViewColumn DisplayMemberBinding="{Binding Height}" Header="Height"/>
<GridViewColumn DisplayMemberBinding="{Binding Age}" Header="Age"/>
</GridView.Columns>
</GridView>
</ListView.View>
<ListView.GroupStyle>
<GroupStyle AlternationCount="3">
<GroupStyle.ContainerStyle>
<Style TargetType="GroupItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="GroupItem">
<StackPanel Orientation="Horizontal">
<StackPanel.Resources>
<Style TargetType="StackPanel">
<Setter Property="Background" Value="{Binding RelativeSource={RelativeSource AncestorType=GroupItem, Mode=FindAncestor}, Path=(ItemsControl.AlternationIndex), Converter={StaticResource AltCnvKey}}"/>
</Style>
</StackPanel.Resources>
<ItemsPresenter/>
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
</GroupStyle>
</ListView.GroupStyle>
</ListView>
</Grid>
代码:
using System.Linq;
using System.Windows;
namespace WpfStackOverflow
{
/// <summary>
/// Interaction logic for Window6.xaml
/// </summary>
public partial class Window6 : Window
{
public Window6()
{
InitializeComponent();
this.DataContext = new[] { new { Age = 32, Name = "Name1", Height = 6 }, new { Age = 34, Name = "Name1", Height = 6 }, new { Age = 34, Name = "Name1", Height = 6 }, new { Age = 32, Name = "Name1", Height = 6 }, new { Age = 32, Name = "Name1", Height = 6 }, new { Age = 39, Name = "Name1", Height = 6 }, new { Age = 40, Name = "Name1", Height = 6 } }.ToList();
}
}
}
使用System.Linq;
使用System.Windows;
命名空间WpfStackOverflow
{
///
///Window6.xaml的交互逻辑
///
公共部分类Window6:Window
{
公共窗口6()
{
初始化组件();
this.DataContext=new[]{new{Age=32,Name=“Name1”,Height=6},new{Age=34,Name=“Name1”,Height=6},new{Age=34,Name=“Name1”,Height=6},new{Age=32,new{Age=32,Name=“Name1”,Height=6},new{Age=39,Name=“Name1”,Height=6},new{Age=40,Name=“Name1”,Height=6}.ToList();
}
}
}
Hmm。。。我的第一次尝试是绑定背景色,并将ItemsSource和Item传递给一个多值转换器,以获取Item的索引,然后您可以对照索引-1进行检查。您好!我也尝试过这个方法,但我无法将其应用到我的解决方案中。不知道为什么,可能是MVVM。对不起,我搞砸了。我用这个,效果很好。还有一个问题。我正在使用MVVM并将DoFocus添加到列表中。每次列表返回焦点时,背景着色都会重新运行。如何使行颜色仅在ItemsSource列表为change-remove或add item to the list时运行?您好!我也尝试过这个方法,但我无法将其应用到我的解决方案中。不知道为什么,可能是MVVM。但非常感谢。@HegeGabi我的答案使用WPF本身提供的标准功能,没有额外的逻辑。是的,你说得对,我在WPF方面并不完美。我尝试了您的代码,但ListView中没有任何项。我正在使用ResourceDictionary->MainSkin.xaml,将PropertyGroupDescription放入其中,并将绑定更改为MainViewModel中的列表。ListView中没有数据。当我尝试将DataContext部分放入代码中时,它会给我一条错误消息:“IndexerProperty”问题。是的,如果我在一个单独的窗口尝试,效果会很好。谢谢你的代码和建议,我会继续尝试。谢谢你的指导,我已经成功了!:-)不幸的是,当ListView有数百行时,它的速度很慢。我能加快着色速度吗?谢谢。@gabi寻找虚拟化。