如何动态更改WPF列表视图行背景颜色?

10

我是WPF的新手,我有以下用于列表视图的xaml代码:

<ListView x:Name="listView1" ItemsSource="{Binding Processes1}"  HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Height="470" Margin="10,95,150,6" Width="565" SelectionChanged="NetscalerCfgView_listView1_SelectionChanged">
   <ListView.View>
       <GridView>
           <GridViewColumn Header="Line"  DisplayMemberBinding="{Binding srcCfgLineNum}"/>
           <GridViewColumn Header="Source Config" DisplayMemberBinding="{Binding srcConfigText}"/>
       </GridView>
   </ListView.View>
</ListView>

我有一个名为 SrcListViewInfo 的类,我想在列表视图中显示它:

public class SrcListViewInfo
{
    public int srcCfgLineNum { get; set; }
    public string srcConfigText { get; set; }
}

我已经在 Windows 加载事件中声明了它,就像这样:

public ObservableCollection<SrcListViewInfo> processes1 = null;
processes1 = new ObservableCollection<SrcListViewInfo>();

我想在不同的情况下,在不同的函数中动态地给行背景着色,例如:
case DiffResultSpanStatus.DeleteSource:
    for (i = 0; i < drs.Length; i++)
    {
        SrcListViewInfo newInfo = new SrcListViewInfo();
        newInfo.BackgroundColor = new SolidColorBrush(Colors.Red);
        // newInfo.BackgroundColor = Brushes.Red;
        newInfo.srcCfgLineNum = cnt;
        newInfo.srcConfigText = ((TextLine)source.GetByIndex(drs.SourceIndex + i)).Line;
        // newInfo.BackgroundColor = Brushes.Red; << want to set the color like this.

我尝试使用实心刷子,但似乎没有正常工作。

3个回答

22

你可以直接在XAML中为ListViewItem添加样式,示例如下:

假设你的“Name”变量是一个字符串,你可以尝试使用以下代码:

<ListView Name="whatever">
  <ListView.Resources>
    <Style TargetType="{x:Type ListViewItem}">
      <Style.Triggers>
        <DataTrigger Binding="{Binding Name}"
                      Value="John">
          <Setter Property="Background"
                  Value="Red" />
        </DataTrigger>
      </Style.Triggers>
    </Style>
  </ListView.Resources>
....

现在,任何具有“名称”值为“John”的ListView行都将具有“红色”背景。


5

一种选择

是在 ListView.ItemTemplate 中使用 IMultiValueConverter

<ListView DataContext="{Binding}" ItemsSource="{Binding Models}" AlternationCount="3" >
        <ListView.ItemTemplate>
            <DataTemplate>
                <StackPanel Orientation="Horizontal">
                    <TextBlock Text="{Binding Name  }"/>
                    <TextBlock Text="{Binding Desc }"/>
                    <StackPanel.Background> 
                            <MultiBinding Converter="{StaticResource BackConverter}">
                                <Binding />
                                <Binding RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType=ItemsControl}"/>
                            </MultiBinding> 
                    </StackPanel.Background>
                </StackPanel>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>


public class BackConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        // write your logic (You have the model and the view model)

        var index = ((ItemsControl)values[1]).Items.IndexOf(values[0]);
        if (index % 2 == 0)
            return Brushes.Gray;
        return Brushes.White;
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

另一种选择

是在ListView.ItemContainerStyle中使用ItemsControl.AlternationIndex

<ListView DataContext="{Binding}" ItemsSource="{Binding Models}" AlternationCount="3" >
        <ListView.ItemContainerStyle>
            <Style TargetType="ListViewItem">
                <Style.Triggers>
                    <Trigger Property="ItemsControl.AlternationIndex"  Value="0">
                        <Setter Property="Background" Value="Red" />
                    </Trigger>
                    <Trigger Property="ItemsControl.AlternationIndex"  Value="1">
                        <Setter Property="Background" Value="Green" />
                    </Trigger>
                    <Trigger Property="ItemsControl.AlternationIndex"  Value="2">
                        <Setter Property="Background" Value="Blue" />
                    </Trigger>
                </Style.Triggers>
            </Style>
        </ListView.ItemContainerStyle>
    </ListView>

编辑

public MainWindow()
{
     InitializeComponent();
     lv.ItemsSource = new List<string> { "a", "b", "c", "d", "e" };
}

谢谢。我认为第二种方法更好。你能告诉我相应的代码是什么吗? - PKB85
它的功能很好,但是静态的。我想为特定条件(在单独的函数下)设置颜色,而不是默认设置。 - PKB85
我知道,这就是 AlternationIndex 的作用。这就是为什么我先写了第一种方法。在转换器中运用你的逻辑。 - rmojab63
你也可以使用其他面板/控件。 - rmojab63
谢谢,我会尝试的。只有一个问题,Ivalueconverter下的对象是类中的一个单独函数,而我想要实际更新它的函数在不同的位置/函数中,那么我该如何确保它能够正常工作呢? - PKB85
显示剩余6条评论

1
经过一番搜索,我找到了自己的解决方法。我正在使用Listview.ItemsSource,并将List作为源。然后,我可以在列表中设置特定ListViewItem的背景色,然后只需刷新listview即可。
XAML:
 <ListView x:Name="listView" ScrollViewer.CanContentScroll="True" ScrollViewer.VerticalScrollBarVisibility="Auto" Grid.Row="1">
                <ListView.View>
                    <GridView>
                        <GridViewColumn Header="IP"  DisplayMemberBinding="{Binding IP}" Width="Auto"/>
                        <GridViewColumn Header="PING" DisplayMemberBinding="{Binding Ping}" Width="Auto"/>
                        <GridViewColumn Header="Host Name" DisplayMemberBinding="{Binding DNS}" Width="Auto"/>
                        <GridViewColumn Header="Mac" DisplayMemberBinding="{Binding MAC}" Width="Auto"/>
                        <GridViewColumn Header="Výrobce" DisplayMemberBinding="{Binding Manufacturer}" Width="Auto"/>
                    </GridView>
                </ListView.View>
            </ListView>

使用灰色背景填充ListView中的项目:

List<ListViewItem> ITEMS = new List<ListViewItem>();
private void button_Click(object sender, RoutedEventArgs e)
{
    for (int i = 1; i < 20; i++)
    {
        ListViewItem OneItem = new ListViewItem();
        OneItem.Background = Brushes.LightGray;
        OneItem.Content = new Device() { IP = "1.1.1.1", Ping = "30ms", DNS = "XYZ", MAC = "2F:3C:5F:41:F9", Manufacturer = "Intel" };
        ITEMS.Add(OneItem);
        listView.ItemsSource = ITEMS;
    }
    listView.Items.Refresh();
}
public class Device
{
    public string IP { get; set; }
    public string Ping { get; set; }
    public string DNS { get; set; }
    public string MAC { get; set; }
    public string Manufacturer { get; set; }
}

创建行改变颜色的方法:
private void ChangeRowColor(int RowIndex,SolidColorBrush NewBackground)
{
    ITEMS[RowIndex].Background = NewBackground;
    listView.Items.Refresh();
}

并使用它:

private void button1_Click(object sender, RoutedEventArgs e)
{
    ChangeRowColor(4, Brushes.Green);
}

如果我在list<T>中使用自定义类名,它仍然可以工作吗? - Saud Khan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接