Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/258.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# WPF Listview按数据组而非行替换行背景_C#_Wpf_Xaml_Listview - Fatal编程技术网

C# WPF Listview按数据组而非行替换行背景

C# WPF Listview按数据组而非行替换行背景,c#,wpf,xaml,listview,C#,Wpf,Xaml,Listview,我找不到解决我的问题/想法的方法,我希望有人能帮助我。 在WPF中,我有一个CollectionViewSource,这取决于IEnumerable。 项目包含姓名、身高、年龄字段。 在Xaml中,ListView的ItemsSource=“{Binding CollectionViewSource.View}” 我知道,Listview有一个AlternationCount属性,可以更改行背景色 但我只想在“年龄”字段数据与上述行的年龄数据不同时更改行背景色 这样,按年龄排序: 只有当年龄数

我找不到解决我的问题/想法的方法,我希望有人能帮助我。 在WPF中,我有一个
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寻找虚拟化。