【问题标题】:How to change WPF listview row background colour dynamically?如何动态更改 WPF listview 行背景颜色?
【发布时间】:2017-02-16 16:57:19
【问题描述】:

我是 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.

我尝试过实体刷,但它似乎无法正常工作。

【问题讨论】:

    标签: wpf


    【解决方案1】:

    您可以直接在 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 行都将具有“红色”背景

    【讨论】:

      【解决方案2】:

      一个选项

      就是在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" };
      }
      

      【讨论】:

      • 谢谢。我认为第二种方法更好。你能告诉我对应的代码是什么吗?
      • 这里我使用了 MVVM 方法(google it)。但是,您可以简单地设置 ItemsSource 并查看结果。我添加了一个非常简单的例子。
      • 它工作正常但静态。我只想为特定条件(在单独的函数下)设置颜色,而不是默认设置。
      • 例如,她是我想要为 3 种不同情况动态更新颜色值的函数。公共无效结果(DiffList_TextFile 源,DiffList_TextFile 目标,ArrayList DiffLines,双秒){ listView1.ItemsSource = processes1; switch (drs.Status) { case DiffResultSpanStatus.DeleteSource: case DiffResultSpanStatus.NoChange:
      • 我知道,这就是AlternationIndex 所做的。这就是我首先编写第一种方法的原因。在转换器中使用您的逻辑。
      【解决方案3】:

      经过一番谷歌搜索后,我发现了自己的解决方案,我使用的是 Listview.ItemsSource,作为源,我使用 List 和 ListViewItems 然后我可以在 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 中使用我的自定义类名会怎样?还能用吗?
      猜你喜欢
      • 1970-01-01
      • 2014-04-05
      • 1970-01-01
      • 2013-07-11
      • 2015-12-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多