2009-09-22 18 views
6

tengo una ObservableCollection de alrededor de 1.000 objetos que necesita ser filtrada (buscado) por el usuario final. El usuario debe poder buscar por nombre o identificación de empleado. El Control de lista consume Empleados y empleados filtrados está cargado con todo en la carga de la página.Filtrado de una ObservableCollection por la entrada del usuario

actualmente lo tengo configurado como tal:

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); 
    } 
} 

Saneamiento se maneja antes de este método.

Esto no huele muy eficiente. ¿Debo usar dos métodos para esto, o hay una mejor manera de manejar el filtrado?

me gustaría mantener a los empleados en un estado sin cambios para que pueda repoblar FilteredEmployees a la lista completa sin chocar con la base de datos de nuevo.

+0

¿Qué tipo de control es su lista? Sería claro si pudiera consumir directamente a los empleados filtrados en lugar de copiarlos, pero con solo 1000 probablemente no importe en absoluto. –

+0

Simplemente un antiguo enlace ListBox normal en los empleados filtrados – Slipfish

Respuesta

1

Parece que usted está tratando de ver si searchText está contenida en el nombre del empleado, o en el número de empleado.

Usted puede hacer esto en su lugar:

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

O usted podría utilizar en lugar de StartsWith IndexOf.

Editar: Otro problema con la lista de controles con grandes cantidades de datos en ellos es que se tarda mucho tiempo en procesarse. Por lo tanto, si lo tiene sin filtrar cuando comienza y Silverlight o WCF o lo que sea que tenga que procesar los 1000 en el control aunque no los vea a todos, puede tomar un poco de tiempo. Silverlight 3 tiene UI Virtualization, que probablemente sería la mejor optimización que podría hacer aquí.

+0

Actualmente está siendo llenado por una puerta de acceso paginada, por lo que no hay problemas allí. – Slipfish

2

Sé que esta es una publicación anterior pero la estaba usando para ayudarme con el aspecto de filtrado y me di cuenta de que SlipFish estaba creando la ObservableCollection haciendo un bucle alrededor de la colección IEnumerable.

Como el constructor ObservableCollection acepta una colección IEnumerable ObservableCollection se podría crear de esta manera:

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

muy útil para saber +1 – electricalbah

1

Tome un vistazo a este post para una colección filtered observable.

+0

intenté con este código, exactamente lo que estaba buscando, ¡gracias por señalar esto! –

Cuestiones relacionadas