如何为WPF中ListView控件的每个项设置不同颜色?
WPF ListView 实现每项随机背景色的解决方案
问题说明
需要为WPF ListView的每个列表项设置不同的随机背景色,此前尝试自定义ControlTemplate的方式出现大量错误,现结合提供的项目代码给出正确实现方式。
错误原因分析
你之前编写的ListView.Resources代码存在两个核心问题:
- 自定义的
ControlTemplate完全替换了ListViewItem的默认结构,导致原本的GridView列内容无法显示——模板里只放了一个绑定Name的TextBlock,但你的实体类中并没有Name属性,而是GameName。 - 直接替换Template的方式不适合带GridView的ListView,正确做法是通过设置
ListViewItem的Background属性实现背景色自定义,保留原有的GridView布局。
正确实现步骤
1. 修改实体类Cropped_Info
添加BackgroundColor属性,用于存储每个项的随机背景色:
using System.Windows.Media; namespace Lab_ListView { class Cropped_Info { private string m_GameName; private string m_Rating; private double m_Price; private Brush m_BackgroundColor; public string GameName { get => m_GameName; set => m_GameName = value; } public string Rating { get => m_Rating; set => m_Rating = value; } public double Price { get => m_Price; set => m_Price = value; } public Brush BackgroundColor { get => m_BackgroundColor; set => m_BackgroundColor = value; } public Cropped_Info() { GameName = " "; Rating = " "; Price = 0.0; BackgroundColor = Brushes.White; } } }
2. 修改ListView的XAML代码
在VideoGameListView内部添加ListViewItem的样式,绑定Background到实体类的BackgroundColor属性,同时保留原有的GridView布局:
<ListView x:Name="VideoGameListView" HorizontalAlignment="Left" Height="166" Margin="40,203,0,0" VerticalAlignment="Top" Width="447"> <ListView.Resources> <Style TargetType="ListViewItem"> <Setter Property="Background" Value="{Binding BackgroundColor}"/> <!-- 可选:设置选中时的背景色,避免覆盖自定义背景 --> <Style.Triggers> <Trigger Property="IsSelected" Value="True"> <Setter Property="Background" Value="#FF92C6F9"/> <Setter Property="Foreground" Value="Black"/> </Trigger> </Style.Triggers> </Style> </ListView.Resources> <ListView.View> <GridView> <GridViewColumn Header="Game Name" DisplayMemberBinding="{Binding GameName}"/> <GridViewColumn Header="Rating" DisplayMemberBinding="{Binding Rating}"/> <GridViewColumn Header="Price" DisplayMemberBinding="{Binding Price}"/> </GridView> </ListView.View> </ListView>
3. 修改后台代码,生成随机颜色
在创建Cropped_Info对象时,生成随机RGB颜色并赋值给BackgroundColor属性:
private void DispatcherTimer_Tick(object sender, EventArgs e) { vg = new Cropped_Info(); vg.GameName = randStr(5) + " " + counter.ToString(); // 生成随机背景色(范围200-255保证颜色较浅,文字清晰) Color randomColor = Color.FromRgb((byte)random.Next(200,256), (byte)random.Next(200,256), (byte)random.Next(200,256)); vg.BackgroundColor = new SolidColorBrush(randomColor); VideoGameListView.Items.Add(vg); if(counter == 1000) { dispatcherTimer.Stop(); } counter++; }
额外说明
- 如果需要保留此前的选中样式逻辑,可以在
Style.Triggers里添加MultiTrigger,但注意不要替换整个Template,只修改Background和Foreground属性即可。 - 推荐使用
ObservableCollection<Cropped_Info>替代直接往Items里添加项,这样数据变更时UI会自动更新,更符合WPF的设计思想。
内容的提问来源于stack exchange,提问作者Daniel Lip
相关产品推荐
相关产品推荐

