HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

Checkbox binding to change the ListView's items source

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
thesourcecheckboxitemsbindingchangelistview

Problem

I am using a checkbox to filter some components on my ListView by changing the variable's content which is bound to this ListView:

C#

#region Constructor

void CreateAllParts()
{
// GetParts() returns List. Now we can pour it's results
// using the following select in List on the
// fly.
// allpvms: All Part View Models.
allpvms = _partRepository.GetParts().Select(p => new EditPartViewModel(p)).ToList();

foreach (EditPartViewModel cvm in allpvms)
{
cvm.PropertyChanged += this.OnPartViewModelPropertyChanged;
}

this.AllParts = new ObservableCollection(allpvms);
this.AllParts.CollectionChanged += this.OnCollectionChanged;
}

void LoadErrorParts()
{
if (_errorParts)
{
this.AllParts = new ObservableCollection(allpvms.Where(p => p.Price == null));
this.AllParts.CollectionChanged += this.OnCollectionChanged;
}
else
{
this.AllParts = new ObservableCollection(allpvms);
this.AllParts.CollectionChanged += this.OnCollectionChanged;
}
}

#endregion // Constructor

#region Public Interface

///
/// Returns a collection of all the EditPartViewModel objects.
///
public ObservableCollection AllParts
{
get
{
return _allParts;
}
set
{
_allParts = value;
OnPropertyChanged("AllParts");
}
}

public bool ErrorParts
{
get
{
return _errorParts;
}
set
{
_errorParts = value;
OnPropertyChanged("ErrorParts");
LoadErrorParts();
}
}

#endregion // Public Interface


XAML












ListViews content get collected by a DataTemplate in the Resources.

Is the way I use the binding concept look okay? Any corrections or "good practice" methods I should consider when doing similar procedures?

Solution

You should probably bind ItemsSource to CollectionView, instead of binding to ObservableCollection. This way you don't have to recreate collection every time you want to apply your filter. May look like this:

//constructor
Parts = new ObservableCollection(allpvms);
PartsCollectionView = (ListCollectionView)CollectionViewSource.GetDefaultView(Parts);

...............

public ListCollectionView PartsCollectionView { get; private set; }

public bool ErrorParts
{
    get
    {
        return _errorParts;
    }
    set
    {
        _errorParts = value;
        OnPropertyChanged("ErrorParts");
        PartsCollectionView.Filter = value ? (Predicate)(p => ((EditPartViewModel)p).Price == null) : null;
    }
}


Also if your viewmodles can contain errors, you should probably move your error-checking logic inside those viewmodels. So instead of writing p.Price == null you would write p.HasErrors or something.

You should also indicate, that ErrorParts is actually a bool property, unlike AllParts which is a collection. DisplayErrors or ShowErrors or FilterErrors etc. are better names for this property in my opinion.

Code Snippets

//constructor
Parts = new ObservableCollection<EditPartViewModel>(allpvms);
PartsCollectionView = (ListCollectionView)CollectionViewSource.GetDefaultView(Parts);

...............

public ListCollectionView PartsCollectionView { get; private set; }

public bool ErrorParts
{
    get
    {
        return _errorParts;
    }
    set
    {
        _errorParts = value;
        OnPropertyChanged("ErrorParts");
        PartsCollectionView.Filter = value ? (Predicate<Object>)(p => ((EditPartViewModel)p).Price == null) : null;
    }
}

Context

StackExchange Code Review Q#70776, answer score: 4

Revisions (0)

No revisions yet.