Skip to content

Instantly share code, notes, and snippets.

@dereklakin
Created March 22, 2012 08:12
Show Gist options
  • Save dereklakin/2157035 to your computer and use it in GitHub Desktop.
Save dereklakin/2157035 to your computer and use it in GitHub Desktop.
Responsive Filtering
namespace GateGuru.Pages.Search
{
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using PixelLab.Common;
/// <summary>
/// Provides the view model for the <see cref="Search"/> page.
/// </summary>
public class SearchViewModel : PropertyChangeBase
{
private readonly BackgroundWorker worker;
private IOrderedEnumerable<Data> allSorted;
private List<Data> current;
private string query = string.Empty;
/// <summary>
/// Initializes a new instance of the <see cref="SearchViewModel"/> class.
/// </summary>
public SearchViewModel()
{
this.Results = new ObservableCollection<Data.Airport>();
this.worker = new BackgroundWorker
{
WorkerSupportsCancellation = true
};
this.worker.DoWork += this.Filter;
this.worker.RunWorkerCompleted += this.Filter_Complete;
}
/// <summary>
/// Gets or sets the search query.
/// </summary>
/// <value>The search query.</value>
public string Query
{
get { return this.query; }
set
{
if (this.UpdateProperty("Query", ref this.query, value))
{
this.StartFilter(value.ToLowerInvariant());
}
}
}
/// <summary>
/// Gets the results.
/// </summary>
/// <value>The results.</value>
public ObservableCollection<Data> Results { get; private set; }
/// <summary>
/// Loads the data.
/// </summary>
public void LoadData()
{
// TODO: Initialize this.allSorted
this.current = this.allSorted.ToList();
this.current.ForEach(a => this.Results.Add(a));
}
private void Filter(object sender, DoWorkEventArgs e)
{
var query = (string)e.Argument;
if (string.IsNullOrWhiteSpace(query))
{
e.Result = this.allSorted;
}
else
{
e.Result = from a in this.current
where a.Name.ToLowerInvariant().Contains(query)
select a;
}
}
private void Filter_Complete(object sender, RunWorkerCompletedEventArgs e)
{
if (!e.Cancelled)
{
var filtered = (IEnumerable<Data>)e.Result;
this.Results.Clear();
filtered.ForEach(a => this.Results.Add(a));
}
}
private void RefilterOnCompletion(object sender, RunWorkerCompletedEventArgs e)
{
this.worker.RunWorkerCompleted -= this.RefilterOnCompletion;
this.worker.RunWorkerAsync(this.Query.ToLowerInvariant());
}
private void StartFilter(string query)
{
if (this.worker.IsBusy)
{
if (!this.worker.CancellationPending)
{
this.worker.RunWorkerCompleted += this.RefilterOnCompletion;
this.worker.CancelAsync();
}
}
else
{
this.worker.RunWorkerAsync(query.ToLowerInvariant());
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment