Question

Here is a style that hides the ListViewItem when bound to a record with a property ALIVE=false, and then sets the color of the same ListViewItem background based on an AlternationIndex:

 <Style x:Key="alternatingListViewItemStyle" TargetType="{x:Type ListViewItem}">
    <Style.Triggers>
        <DataTrigger Binding="{Binding Path=ALIVE}" Value="False">
            <Setter Property="Visibility" Value="Collapsed" />
        </DataTrigger>
        <Trigger Property="ItemsControl.AlternationIndex" Value="1">
             <Setter Property="Background" Value= "LemonChiffon"></Setter>
        </Trigger>
        <Trigger Property="ItemsControl.AlternationIndex" Value="2">
             <Setter Property="Background" Value="White"></Setter>
        </Trigger>
    </Style.Triggers>
 </Style>

The intent is to:

  1. First, hide all records that have ALIVE set to false
  2. Then, apply alternating background colors to the remaining rows.

What actually happens:

  1. The records with ALIVE set to false are hidden
  2. The alternating background is applied to ALL rows, thus breaking the alternation effect (Eg: instead of getting yellow/white/yellow/white, you might get yellow/yellow/white/yellow)

Now the question:

Is it possible to somehow control the AlternationIndex (by telling it to skip rows that should be hidden)?


One alternative (that I don't like):

Instead of hiding rows with a style, filter out the not ALIVE rows from the underlying collection (that gets bound to the ListView)

Was it helpful?

Solution

A simple LINQ in the getter of your collection property would save you time instead of an UI oriented solution.. Here is how it would look like..

    private ObservableCollection<YourClass> _allDataItems;
    //The entire collection
    public ObservableCollection<YourClass> AllDataItems
    {
        get
        {
            return _allDataItems;
        }
        set
        {
            if( _allDataItems == value ) { return; }
            _allDataItems = value;
            if( _allDataItems != null )
            {
                _allDataItems.CollectionChangedEvent += ( s, e ) =>
                {
                    RaisePropertyChanged( "DisplayedDataItems" );
                };
            }
            RaisePropertyChanged( "AllDataItems " );
            RaisePropertyChanged( "DisplayedDataItems" );
        }
    }

    //The displayed colelction
    public ObservableCollection<YourClass> DisplayedDataItems
    {
        get
        {
            return AllDataItems.Where( adi => adi.ALIVE == true );
        }
    }

And you can simply bind DisplayedDataItems to your ListView.

OTHER TIPS

I agree that the most straightforward way would be to filter your data source before binding. However if you are unable to take that course, you could filter your data source in XAML by using an ObjectDataProvider and CollectionViewSource) coupled with your style for alternating row color). See the filtering example here: http://www.galasoft.ch/mydotnet/articles/article-2007081301.aspx

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top