2

I have an observable collection of objects. I wish to bind a gridview to this observable collection. But there is a constraint that only objects whose property x has value a, must be binded

How to do that?

I got it working using CollectionView and filter. For others benefit the code is as follows

Solution :

public class CustomerViewModel
    {       
       public ObservableCollection<Customer> Customers
       {
           get;
           set;
       }


       private ICollectionView _filteredCustomerView;
       public ICollectionView FilteredCustomers
       {
           get { return _filteredCustomerView; }
       }


       public CustomerViewModel()
       {
           this.Customers= new ObservableCollection<Customer>();               
           Customers= GetCustomer();
           _filteredCustomerView= CollectionViewSource.GetDefaultView(Customers);
           _filteredCustomerView.Filter = MyCustomFilter;

       }


       private bool MyCustomFilter(object item)
       {
           Customer cust = item as Customer;
           return (cust.Location == "someValue");

       }
    }
xaria
  • 842
  • 5
  • 24
  • 47

3 Answers3

4

You should use filtering

Sergey Vedernikov
  • 7,609
  • 2
  • 25
  • 27
0

I prefer using LINQ.

var result = YourCollection.Where(p => p.x.HasValue).ToObservableCollection();

But you should write your own extension to convert to ObservableCollection.

public static ObservableCollection<T> ToObservableCollection<T>
              (this IEnumerable<T> source)
{
    if (source == null)
        throw new ArgumentNullException("source");

    return new ObservableCollection<T>(source);
}

Good luck!

Community
  • 1
  • 1
Homam
  • 23,263
  • 32
  • 111
  • 187
  • 3
    But changes in the source collection won't propagate to the result collection, so updates won't reflect in the UI automatically. Using the CollectionView and filter avoids that. – mancaus Feb 22 '11 at 07:58
  • That extension method is just a wrapper for 'new'. Seems like overkill. – Ed S. Feb 22 '11 at 07:59
  • @mancaus: I agree, but I thought of reassign the new result as a datasource. I know it's not tuned, but with small amount of data it's OK and easier to deal. – Homam Feb 22 '11 at 09:00
  • @Ed S: Yes, It's just a wrapper, but it'll be more readable. :) – Homam Feb 22 '11 at 09:04
0

I think you could achieve this in XAML by putting a DataTrigger on the style of your GridView. Something like this:

<DataGrid>
    <DataGrid.Resources>
        <Style TargetType="{x:Type DataGridRow}">
            <DataTrigger Binding="{Binding IsFiltered}" Value="True">
                <Setter Property="Visibility" Value="Visible" />
            </DataTrigger>
            <DataTrigger Binding="{Binding IsFiltered}" Value="False">
                <Setter Property="Visibility" Value="Collapsed" />
            </DataTrigger>
        </Style>
    </DataGrid.Resources>
</DataGrid>
Phil Gan
  • 2,813
  • 2
  • 29
  • 38