5
votes

I have a class to color alternate the background of item, but if I delete a item, the background color does not update. Is there a way to refresh the background color after deleting an item?

The code for alterante color. class listview:

public class AlternatingRowListView : ListView
{
    protected override void PrepareContainerForItemOverride(DependencyObject element, object item)
    {
        base.PrepareContainerForItemOverride(element, item);
        var listViewItem = element as ListViewItem;
        if (listViewItem != null)
        {
            var index = IndexFromContainer(element);

            if (index % 2 == 0)
            {
                listViewItem.Background = new SolidColorBrush(Colors.LightBlue);
            }
            else
            {
                listViewItem.Background = new SolidColorBrush(Colors.Transparent);
            }
        }

    }
}

code xaml:

<local:AlternatingRowListView x:Name="listview">
        <ListViewItem>item 1</ListViewItem>
        <ListViewItem>item 2</ListViewItem>
        <ListViewItem>item 3</ListViewItem>
        <ListViewItem>item 4</ListViewItem>
        <local:AlternatingRowListView.ItemTemplate>
            <DataTemplate>

            </DataTemplate>
        </local:AlternatingRowListView.ItemTemplate>
</local:AlternatingRowListView>

Thanks in advance.

2

2 Answers

6
votes

You just need to extend your already extended AlternatingRowListView control a bit to achieve what you need.

You can monitor whenever an item gets removed from the list by subscribing to the VectorChanged event of the Items, and then you just loop through all the already realized items below(visually) the removed item and change their background colors accordingly.

Something like this would do -

public AlternatingRowListView()
{
    DefaultStyleKey = typeof(ListView);

    Items.VectorChanged += OnItemsVectorChanged;
}

private void OnItemsVectorChanged(IObservableVector<object> sender, IVectorChangedEventArgs args)
{
    // When an item is removed from the list...
    if (args.CollectionChange == CollectionChange.ItemRemoved)
    {
        var removedItemIndex = (int)args.Index;

        // We don't really care about the items that are above the deleted one, so the starting index
        // is the removed item's index.
        for (var i = removedItemIndex; i < Items.Count; i++)
        {
            if (ContainerFromIndex(i) is ListViewItem listViewItem)
            {
                listViewItem.Background = i % 2 == 0 ? 
                    new SolidColorBrush(Colors.LightBlue) : new SolidColorBrush(Colors.Transparent);
            }
            // If it's null, it means virtualization is on and starting from this index the container
            // is not yet realized, so we can safely break the loop.
            else
            {
                break;
            }
        }
    }
}
0
votes

if you are searching alternate odd/even row colors:

in app.xml

<Application
  ...
  <Application.Resources>
    <AlternateColorConverterx:Key="AlternateColorConverter" />
   ...
  </Application.Resources>

generate a new class namely AlternateColorConverter.cs
(modify your hex colors.)

  class AlternateColorConverter : IValueConverter
{
    private static int idx_=-1;
    private static int odd_=0;
    private static int idx(int offset)
    {
        int idx_before = idx_;
        idx_ = (idx_ + 1) % (offset);

        if (idx_ < idx_before) odd_=(odd_+1)%2;
        return odd_;
    }

    public static Color GetColorFromHex(string hexString)
    {
        Color x = (Color)XamlBindingHelper.ConvertValue(typeof(Color), hexString);
        return x;
    }

    public object Convert(object value, Type targetType, object parameter, string language)
    {
        int param = System.Convert.ToInt32(parameter);
        return new SolidColorBrush(ColorUtils.GetColorFromHex((idx(param) == 0) ? "#F24C27" : "#FBBA42"));
    }

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

and in yourpage.xml.cs :
(where ConverterParameter(offset) depends on column count. usually 2)

<ListView HorizontalAlignment="Stretch" Style="{StaticResource ListViewStyle}">
        <ListView.ItemContainerStyle>
            <Style TargetType="ListViewItem">
                <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
                <Setter Property="MaxHeight" Value="20"/>
                <Setter Property="MinHeight" Value="20"/>
                <Setter Property="Padding" Value="0"/>
            </Style>
        </ListView.ItemContainerStyle>
        <ListView.ItemTemplate>
            <DataTemplate x:DataType="Models:YourObservableArray">
                <Grid HorizontalAlignment="Stretch" Margin="0">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="180*"/>
                        <ColumnDefinition Width="100*"/>
                    </Grid.ColumnDefinitions>
                    <Border Background="{Binding Converter={StaticResource AlternateColorConverter},ConverterParameter=2}" HorizontalAlignment="Stretch" Grid.Column="0"  Margin="0">
                        <TextBlock Text="{x:Bind Field1}" HorizontalAlignment="Stretch"/>
                    </Border>
                    <Border Background="{Binding Converter={StaticResource AlternateColorConverter},ConverterParameter=2}" HorizontalAlignment="Stretch" Grid.Column="0"  Margin="0">
                        <TextBlock Text="{x:Bind Field2}" HorizontalAlignment="Stretch"/>
                    </Border>
                </Grid>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>