Zebra-Color-Style ListViewItem 行按第二列中的文本分组

Zebra-Color-Style ListViewItem rows GROUPED by text in 2nd column

我想为一组 ListViewItems 的背景着色,以便我可以看到按第 2 列中的值分组的情况。

这是一个示例 C# 代码:

class Bla
{
    public int col1 { get; set; }
    public int col2 { get; set; }
}

public partial class MainWindow : Window
{
    ObservableCollection<Bla> obsListItems = new ObservableCollection<Bla>();

    public MainWindow()
    {
        InitializeComponent();

        obsListItems.Add(new Bla
        {
            col1 = 1, col2 = 111
        });
        obsListItems.Add(new Bla
        {
            col1 = 2, col2 = 111
        });
        obsListItems.Add(new Bla
        {
            col1 = 3, col2 = 222
        });
        obsListItems.Add(new Bla
        {
            col1 = 4, col2 = 333
        });
        obsListItems.Add(new Bla
        {
            col1 = 5, col2 = 333
        });
        obsListItems.Add(new Bla
        {
            col1 = 6, col2 = 444
        });

        obsListItems.Add(new Bla
        {
            col1 = 7, col2 = 444
        });

        Zebra.ItemsSource = obsListItems;

        this.DataContext = this;
    }
}

如您所见,col1 的值是唯一的,而 col2 具有重复数字。

如果 col2 的值为 111 和 333,则背景颜色应该变为 - 比方说 - 绿色,而其余部分保持其背景颜色。

顺便说一下:当然这些都是模型......在未来的使用中,将会有更多具有不同值的 ListViewItems,直接来自数据库并按第二列的值排序。

这是我的 WPF 控件:

<ListView x:Name="Zebra"
              ItemsSource="{Binding Path=obsListItems}"
              SelectionMode="Single" Background="#FFC8F0F1" FontSize="16" Margin="0,0,0,10">
        <ListView.View>
            <GridView>
                <GridViewColumn Header="Column 1"
                                        DisplayMemberBinding="{Binding col1}"
                                        Width="70" />
                <GridViewColumn Header="Column 2"
                                        DisplayMemberBinding="{Binding col2}"
                                        Width="90" />
            </GridView>
        </ListView.View>
    </ListView>

@offtopic:一旦我删除了这一行:

Zebra.ItemsSource = obsListItems;

它不再工作了。我认为使用 ItemsSource="{Binding Path=obsListItems}" 可以使用 this.Datacontext = this。有人知道为什么吗?

Anyone know why?

您只能绑定到 public 属性:

public ObservableCollection<Bla> obsListItems { get; } new ObservableCollection<Bla>();

关于 "zebra" 着色,您应该可以使用转换器来完成。请参考以下代码示例:

namespace WpfApplication1
{
    public class ColorConverter : IValueConverter
    {
        private static List<System.Windows.Media.Brush> _brushesToChooseFrom = new List<System.Windows.Media.Brush>()
        {
            System.Windows.Media.Brushes.Green,
            System.Windows.Media.Brushes.Red,
            System.Windows.Media.Brushes.Violet,
            System.Windows.Media.Brushes.Yellow
        };
        private Dictionary<int, System.Windows.Media.Brush> _usedBrushes = new Dictionary<int, System.Windows.Media.Brush>();
        private int index = 0;

        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            int col2 = (int)value;
            if(!_usedBrushes.ContainsKey(col2))
            {
                System.Windows.Media.Brush brush = _brushesToChooseFrom[index++];
                if (index == _brushesToChooseFrom.Count)
                    index = 0;
                _usedBrushes.Add(col2, brush);
            }

            return _usedBrushes[col2];
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
}

<ListView x:Name="Zebra"
              ItemsSource="{Binding Path=obsListItems}"
              SelectionMode="Single" Background="#FFC8F0F1" FontSize="16" Margin="0,0,0,10"
              xmlns:local="clr-namespace:WpfApplication1">
    <ListView.Resources>
        <local:ColorConverter x:Key="conv" />
    </ListView.Resources>
    <ListView.ItemContainerStyle>
        <Style TargetType="ListViewItem">
            <Setter Property="Background" Value="{Binding col2, Converter={StaticResource conv}}" />
        </Style>
    </ListView.ItemContainerStyle>
    <ListView.View>
        <GridView>
            <GridViewColumn Header="Column 1"
                                        DisplayMemberBinding="{Binding col1}"
                                        Width="70" />
            <GridViewColumn Header="Column 2"
                                        DisplayMemberBinding="{Binding col2}"
                                        Width="90" />
        </GridView>
    </ListView.View>
</ListView>