SearchAll es un control de WPF que realiza de filtrados
de manera extremadamente sencilla. SearchAll reduce el tiempo y el esfuerzo y
posee una interfaz muy amigable y cuidada. Este control está basado en el
control de búsqueda de la página de formación Pluralsight, con la diferencia de que SearchAll es válido para cualquier
tipo de datos, ya que es un control completamente genérico.
Vamos a ver todas sus bondades.
Siempre he pretendido buscar una técnica que me librara de ese gasto tan tedioso de tiempo, recurso y espacio que conlleva el el espacio reservado al filtrado en nuestros formularios. SearchAll cubre una gran parte de las necesidades de filtrado, con un código mínimo y con un gran resultado.
Muy importante:
SearchAll soporta la versión 4.5.2 .NET Framework y posteriores
Si tu instalas el paquete de Nuget sobre una aplicación WPF con una versión de .NET Framework inferior a la 4.5.2, Visual Studio instalará correctamente el complemento pero el assembly no aparecerá en references.
NO hemos testeado el control para UWA, pero la idea es si
esta plataforma tiene salida, darle soporte en el futuro.
SearchAll es un control de código abierto que está
disponible en GitHub y en descarga por Nuget.
El Control
SearchAll es un control de composición muy simple. Está
formado por tres elementos principales:
- Text to search (Texto a bucar) .- · Es la parte donde se introduce el texto a
filtrar, cuando hacemos click en esta zona, aparece un popup de búsqueda que
ocupa prácticamente la totalidad de la pantalla, y según vamos introduciendo caracteres,
nos van apareciendo las coincidencias (en caso de haberlas claro está).
- Cancel Filter Button (Botón de Cancelación de Filtro) .- · Este botón está disponible cuando hemos
realizado un filtrado y nos proporciona la opción de cancelar el filtrado.
- Filter Button (Botón de Filtrado).- Su función es filtrar nuestra fuente de datos
(ItemsSource), pero este botón solo tiene utilidad cuando se ha añadido el
texto a buscar mediante código (MVVM-binding o CodeBihind), ya que normalmente
este texto se rellena automáticamente al aceptar el filtrado (con la tecla
Return) desde el popup de búsqueda.
Un primer vistazo a una ejecución simple:
See you in HD |
Instalación
La instalación del control SearchAll la realizaremos mediante un paquete de Nuget:
1.- Instalaremos
el paquete.
Install-Package MoralesLarios.CustomsControls
See you in HD |
2.- En el WPF Toolbox
haremos click-derecho y eligiremos ‘Choose Items’ >> Browse. Buscaremos
la librería MoralesLarios.CustomControls.dll
en la carpeta bin de nuestro proyecto. Recordar que es necesario haber compilado el Proyecto.
Click OK,
y la tendremos disponible en la ventana de herramientas para utilizar.
In movimiento.
See you in HD |
Solo necesitamos arrastrar el control a nuestra window.
SearchAll es un control muy sencillo que para funcionar, solo
necesita de la configuración de su propiedad ItemsSource. Normalmente
esta fuente de datos, suele coincidir con la fuente de datos de los controles
contenedores, tales como (DataGrid,
ListBox, ListView, ComboBox,
etc), los cuales serán filtrados. Esto lo podemos hacer mediante MVVM
o CodeBehind.
Si no configuramos la
propiedad ItemsSource del control, esté arrancará deshabilitado
XAML
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:WpfApplication17" xmlns:CustomsControls="clr-namespace:MoralesLarios.CustomsControls;assembly=MoralesLarios.CustomsControls" x:Class="WpfApplication17.MainWindow" mc:Ignorable="d" Title="MainWindow" Height="261.112" Width="525"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="46"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <CustomsControls:SearchAll x:Name="searchAll" HorizontalAlignment="Left" Margin="50,10,0,0" VerticalAlignment="Top" Height="29" Width="270" /> <DataGrid x:Name="dgData" Grid.Row="1" AutoGenerateColumns="True" /> </Grid> </Window>
Code Behind:
using System.Linq; using System.Windows; namespace WpfApplication17 { public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); var data = typeof(Enumerable).GetMethods(); dgData.ItemsSource = data; searchAll.ItemsSource = data; } } }
En acción:
See you in HD |
En el
primer paso para filtrar hemos pulsado la Tecla Enter.
En el Segundo hemos pulsado un link de opción.
Como trabaja
Explicado de forma sencilla SearchAll trabaja buscando u carácter(es)/palabra(s) en todas
las propiedades de los elementos de la secuencia que forman la fuente de datos:
Por defecto solo instanciamos la propiedad ItemsSource.
En movimiento.
See you in HD |
El control SearchAll para realizado su filtrado se
aprovecha de la vista vinculado a la fuente de datos (ICollectionView) de la
propiedad ItemsSource.
Propiedades más importantes
Para mostrar las propiedades más importantes del control,
usaremos una aplicación test de WPF. Esta aplicación tiene un diseño
cuidado y tiene bindeadas las propiedades más importantes del control, para
poder realizar o ver los cambios en tiempo real.
La fuente de datos de la aplicación, consiste en la consulta
de todos los servicios de Windows de la máquina en la que corre (services.msc).
Para ello hacemos uso d ela clase System.ServiceProcess.ServiceController
de .NET Framework.
public class ServiceController { public bool CanPauseAndContinue { get; } public bool CanShutdown { get; } public bool CanStop { get; } public ServiceController[] DependentServices { get; } public string DisplayName { get; set; } public string MachineName { get; set; } public SafeHandle ServiceHandle { get; } public string ServiceName { get; set; } public ServiceController[] ServicesDependedOn { get; } public ServiceType ServiceType { get; } public ServiceControllerStatus Status { get; } }
UI
ItemSource
public IEnumerable<object> ItemsSource { get; set; }
La propiedad de dependencia ItemsSource obtiene o
establece la colección que será filtrada por el control. Esta es la única propiedad
que es necesaria para que el control funcione.
Como hemos dicho anteriormente, si no asignas esta propiedad
el control permanecerá deshabilitado.
Text
public string Text { get; set; }
La propiedad de dependencia Text, obtiene o estable
el contenido a filtrar.
Cuando la propiedad Text, está vacía los botones Filter
y Cancel,
permanecen deshabilitados.
NumberSugerencyElements
public int NumberSugerencyElements { get; set; }
La propiedad de dependencia NumberSugerencyElements obtiene o establece el número máximo de
sugerencias mostradas en el popup de
búsqueda. Esta propiedad es importante a nivel de rendimiento, ya
que si se aplica sobre una colección con un número elevado de elementos y con
un texto de búsqueda poco probable, las tareas pueden ser pesadas, ya que se
debe recorrer prácticamente toda la colección y todas las propiedades. A menor
número, menor trabajo.
20 es el valor por defecto.
En
movimiento
FilterClass
public FilterType FilterClass { get; set; }
La propiedad de dependencia FilterClass obtiene o
estable el modo en que se realizará la búsqueda.
Su tipo de retorno es FilterType y posee estos 5 valores:
- StartWith
- EndWith
- Contains
- Equals
- Custom
Contains
es el valor por defecto.
En nuestra aplicación de pruebas, hemos implementado una forma
amigable para poder cambiar esta propiedad en caliente, y poder ir modificando los
modos de búsqueda sin tener que para la ejecución, cambiar la propiedad y volver
a recompilar. Esto lo podemos distinguir en la parte inferior izquierda de la
aplicación, justo debajo de la etiqueta FilterClass. Para cambiar haremos doble-click
en los textblocks
con la definición de cada una de las posibilidades, al iluminarse nos mostrará
cual es el que está activo.
En
movimiento.
Como se puede observar falta por comentar el último tipo, el
tipo Custom,
este lo dejaremos para un próximo artículo en el que mostraremos un
funcionamiento más avanzado del control.
FieldsSugerenciesSearch
public IEnumerable<string> FieldsSugerenciesSearch { get; set; }
La propiedad de dependencia FieldsSugerenciesSearch obtiene o establece el nombre y el
orden de las propiedades del tipo de la fuente de datos en el que se buscará el
texto de búsqueda. En caso de
coincidir será mostrado en las sugerencias.
El valor por defecto es Null.
En caso de contener el valor por defecto, la búsqueda se realizará en todas y
cada de las propiedades del tipo, por orden de aparición en la clase.
Los ejemplos mostrados en las imágenes, son ejemplos muy
simples, ya que solo hemos utilizado una propiedad a buscar. Este modo me
parecía más didáctico y considero que hace entender mejor su utilidad. Al ser
una colección de cadenas, podremos añadir todas las que queramos.
Para el ejemplo de la izquierda, hemos utilizado el campo DisplayName y para el de la derecha
el campo ServiceName.
En nuestra aplicación de pruebas, como en el caso anterior,
hemos desarrollado un cambio dinámico de propiedades, para poder realizar
también el cambio en caliente, con el mismo objetivo que con la propiedad FilterClass. La forma de cambiarlo
es haciendo click en la etiqueta ‘FieldSearch / SugrenceSearch’.
Así que vamos a verlo en movimiento.
Otro ejemplo con más campos, esta vez en codebehind:
FieldsSearch
public IEnumerable<string> FieldsSearch { get; set; }
La propiedad de dependencia FieldSearch, es prácticamente
igual a FieldsSugerenciesSearch, con la salvedad de que la definición
de campos de FieldSearch se utiliza en el momento de realizar el filtrado
de los datos.
Normalmente las dos propiedades están configuradas con los
mismos valores, pero existen por si por alguna razón se quisieran diferenciar.
Un ejemplo completo con varias propiedades:
Query Filtered Data
Si queremos consultar los datos filtrados, deberemos hacer lo siguiente:
En CodeBehind:
public void QueryFilterData() { /// Use de ReadOnly Dependency Property FilteredItemsSource /// --> ServiceController is a data of mi DataSource (ObservableCollection in ItemsSource) var filteredData = searchAll.FilteredItemdSource.OfType<ServiceController>().ToList(); }
MVVM en el ViewModel:
public void QueryFilterData() { /// Use the ICollectionView of our DataSource /// --> ServiceController is a data of mi DataSource (ObservableCollection in ItemsSource) var filteredData = CollectionViewSource.GetDefaultView(Services).OfType<ServiceController>().ToList(); }
Limitaciones
El Sistema de filtrado del control SearchAll, está basado en Reflection,
por lo que hay determinadas propiedades, que al acceder a ellas por este
método, elevan una excepción. Etas propiedades suelen ser propiedades de apoyo,
generación de proxies dinámicos, etc, que tienen poco valor a nivel
informativo.
La forma de subsanar estos errores es configurando las
propiedades FieldSearch y FieldsSugerenciesSearch , obviando
estás propiedades problemáticas, o eliminándolas de su configuración en caso de
ya estar utilizando estás dependency properties.
Cuando el control encuentra una de estas propiedades,
muestra un mensaje de error, indicando su nombre y la forma de remediar el
error.
En
movimiento
Para el próximo artículo
Para el próximo artículo del control SearchAll dejaremos la parte más avanzada. En ella hablaremos
de Events, Custom Type FilterClass
y algo de su implementación.
AQUÍ ESTÁ EL CÓDIGO DISPONIBLE PARA SU DESCARGA LINK
No hay comentarios :
Publicar un comentario