2009-09-22 5 views
6

J'ai une collection Observable d'environ 1000 objets qui doit être filtrée (recherchée) par l'utilisateur final. L'utilisateur doit pouvoir effectuer une recherche par nom ou par identifiant d'employé. Le contrôle de liste consomme FilteredEmployees et les employés sont chargés avec tout au chargement de la page.Filtrage d'une ObservableCollection par l'entrée de l'utilisateur

J'ai actuellement il mis en place en tant que tel:

public ObservableCollection<EmployeeServicesData> Employees { get; set; } 
public ObservableCollection<EmployeeServicesData> FilteredEmployees { get; set; } 

internal void FilterEmployee(string searchText, bool isByName) 
{ 
    if (searchText.Length > 0) 
    { 
     IEnumerabe<EmployeeServicesData> filter; 

     if (isByName) 
      filter = Employees.Where(x => x.Name.Length >= searchText.Length).Where(x => x.Name.Substring(0, searchText.Length) == searchText.ToUpper()); 
     else 
      filter = Employees.Where(x => x.EmployeeNumber.ToString().Length > searchText.Length).Where(x => x.EmployeeNumber.ToString().Substring(0, searchText.Length) == text); 

     foreach (EmployeeServicesData employee in filter) 
      FilteredEmployees.Add(employee); 
    } 
} 

L'assainissement est traitée avant que cette méthode.

Cela ne sent pas très efficace. Devrais-je utiliser deux méthodes pour cela, ou existe-t-il une meilleure façon de gérer le filtrage? Je souhaite garder les employés dans un état inchangé afin que je puisse repasser FilteredEmployees à la liste complète sans frapper à nouveau la DB.

+0

De quel type est votre liste de contrôle? Ce serait bien si elle pouvait consommer directement les employés filtrés au lieu de les copier, mais avec seulement 1000, ça n'a probablement pas d'importance du tout. –

+0

Juste une ancienne liaison ListBox sur FilteredEmployees – Slipfish

Répondre

1

Il semble que vous essayez de voir si searchText est contenu dans le nom de l'employé ou dans le numéro de l'employé.

Vous pouvez le faire à la place:

x.Name.IndexOf(searchText, StringComparison.OrdinalIgnoreCase) >= 0 
x.EmployeeNumber.ToString().IndexOf(searchText, StringComparison.OrdinalIgnoreCase) >= 0 

Ou vous pouvez utiliser StartsWith au lieu de IndexOf.

Éditer: Un autre problème avec les contrôles de liste contenant de grandes quantités de données est le temps de rendu. Donc, si vous l'avez non filtré lorsque vous démarrez et Silverlight ou WCF ou tout ce qui doit rendre tous les 1000 dans le contrôle, même si vous ne les voyez pas tous, cela peut prendre un peu de temps. Silverlight 3 a UI Virtualization, ce qui serait probablement la meilleure optimisation que vous pourriez faire ici.

+0

Il est actuellement rempli par une passerelle paginée, donc pas de problèmes là-bas. – Slipfish

2

Je sais que c'est un ancien post mais je l'utilisais pour m'aider avec l'aspect filtrage et j'ai remarqué que SlipFish créait ObservableCollection en bouclant autour de la collection IEnumerable.

Comme le constructeur ObservableCollection accepte une collection IEnumerable la ObservableCollection pourrait être créé comme ceci:

FilteredEmployees = new ObservableCollection<EmployeeServicesData>(filter); 
+0

très utile de savoir +1 – electricalbah

1

Jetez un oeil à ce poste pour une collection filtered observable.

+0

a donné ce code un essai, exactement ce que je cherchais, merci de le signaler! –