Johannes Schacht
Johannes Schacht

Reputation: 1334

Partially binding to a list

I have a collection of a few thousand elements and I want to display only a subset of them. Is there a way to bind the collection to a view such that only certain elements, e.g. those with property "Show == true", are displayed? If so, would it still create thousands of UI elements? Or do I have to create a new list of the to-be-shown elements?

Upvotes: 0

Views: 72

Answers (2)

denys-vega
denys-vega

Reputation: 3697

Check CollectionViewSource Class and CollectionViewSource.Filter Event

View(partial example):

<Grid>
    <Grid.DataContext>
        <wpfCalc:StudentList/>
    </Grid.DataContext>

    <Grid.Resources>
        <CollectionViewSource
            Source="{Binding Students,Mode=OneWay}" x:Key="StudentsCollViewSource"
            Filter="StudentsCollViewSource_OnFilter"/>
    </Grid.Resources>

    <ListBox ItemsSource="{Binding Source={StaticResource StudentsCollViewSource}}">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding Name,Mode=OneTime}"/>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
</Grid>

And code behind filter implementation:

private void StudentsCollViewSource_OnFilter(object sender, FilterEventArgs e)
{
    var s = e.Item as Student;
    e.Accepted = s != null && !string.IsNullOrWhiteSpace(s.Name);
}

Upvotes: 1

Saad Abdullah
Saad Abdullah

Reputation: 2432

There are two methods. First one is to use a converter.

 <Window.Resources>
            <local:BoolToVisibilityConverter x:Key="converter"/>
        </Window.Resources>
        <StackPanel>
            <ListView x:Name="listView" ItemsSource="{Binding List}">
                <ListView.ItemTemplate>
                    <DataTemplate >
                        <TextBlock Text="{Binding Name}" Visibility="{Binding IsActive, Converter={StaticResource converter}}"/>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>
        </StackPanel>

//Code Behind

public class BoolToVisibilityConverter : IValueConverter
    {
        #region IValueConverter Members

        public object Convert(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            return (bool)value ? Visibility.Visible : Visibility.Collapsed;
        }

        public object ConvertBack(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            return false; // not needed
        }

        #endregion
    }

Second method is to use linq

    List<MyData> list 
    {
       get
       {
          if(list!=null)
             return list.where( p => p.IsActive == true );
          return null;
       }
       set
       {
          if(list!=value)
             list = value;
        }
    }

Upvotes: 1

Related Questions