Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to change WPF listview row background colour dynamically?

Tags:

wpf

I am new to WPF, I have the following xaml code for list view:

<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>

I have the class SrcListViewInfo which I am displaying in listview:

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

I have declared it in windows load event like this:

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

I want to color the row background dynamically in a different function under different cases dynamically, for example:

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.

I have tried solid brush but it does not seem to be working correctly.

like image 308
PKB85 Avatar asked Feb 16 '17 16:02

PKB85


3 Answers

You can Style the ListViewItem in xaml directly,

Example:

Assuming your "Name" variable is a string, you can try

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

Now any ListView Row with "Name" Value of "John" will have a "Red" Background

like image 80
Saud Khan Avatar answered Oct 19 '22 04:10

Saud Khan


an option

is to use IMultiValueConverter in ListView.ItemTemplate

<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();
    }
}

another option

is to use ItemsControl.AlternationIndex in ListView.ItemContainerStyle

<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>

Edit

public MainWindow()
{
     InitializeComponent();
     lv.ItemsSource = new List<string> { "a", "b", "c", "d", "e" };
}
like image 4
Ron Avatar answered Oct 19 '22 02:10

Ron


After some googling i found out my own solution I am using Listview.ItemsSource and as source i use List with ListViewItems Then i can set background of specify ListViewItem in List, and just refresh 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>

Fill ListView with Items with Gray Background:

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; }
}

Create Method for Row Change Color:

private void ChangeRowColor(int RowIndex,SolidColorBrush NewBackground)
{
    ITEMS[RowIndex].Background = NewBackground;
    listView.Items.Refresh();
}

And use it:

private void button1_Click(object sender, RoutedEventArgs e)
{
    ChangeRowColor(4, Brushes.Green);
}
like image 1
CoRe23 Avatar answered Oct 19 '22 02:10

CoRe23