En este tutorial crearemos un elemento web que contenga un autocompletador de datos extraidos de WCF (JSON) que se almacenarán en la entidad seleccionada a través EntityFramework. ¿Por qué os traigo este tutorial? Os cuento... Mi problema surgió porque no pude encontrar un control que se encargara de las entidades, las cuales necesitaba para seleccionar datos de una lista y ser capaz de almacenarlos en forma de entidad. Encontré algunos ejemplos en la red, pero ninguno de ellos cumplÃa con el ciclo de almacenamiento de la entidad, por lo que no tuve otra opción que construirlo desde cero. También necesitaba otra caracterÃstica, que pudiera ser utilizado en un gridview para su edición. El problema actual con un combobox es que al cargar la página, se cargan necesariamente todos los datos. El control de búsqueda está optimizado para responder a través de (JSON), asà como la consulta (LINQ - AsNoTracking - AsParallel).
Utilizaremos...
- Visual Studio 2013 - Update 5
- AjaxControlToolkit versión=15.1.4.0
- EntityFramework versión=6.1.3
- jQuery versión=2.1.4
- Newtonsoft.Json versión=7.0.1
- Windows Communication Foundation
Cómo llevarlo a cabo...
Cuando el control se ha inicializado, cargamos dinámicamente los archivos JavaScript a los eventos OnClientPopulating, OnClientHiding, OnClientPopulated, OnClientItemSelected.
Private Sub Page_Init(sender As Object, e As EventArgs) Handles Me.Init
Dim Evento_OnClientPopulating As String
Dim Evento_OnClientCompleted As String
Dim Evento_OnClientPopulated As String
Dim Evento_OnClientItemSelected As String
Evento_OnClientPopulating = _
Me.AutoCompleteExtenderClients.ClientID + "_OnClientPopulating"
Evento_OnClientCompleted = _
Me.AutoCompleteExtenderClients.ClientID + "_OnClientCompleted"
Evento_OnClientPopulated = _
Me.AutoCompleteExtenderClients.ClientID + "_OnClientPopulated"
Evento_OnClientItemSelected = _
Me.AutoCompleteExtenderClients.ClientID + "_OnClientItemSelected"
AutoCompleteExtenderClients.OnClientPopulating = _
Me.AutoCompleteExtenderClients.ClientID + "_OnClientPopulating"
AutoCompleteExtenderClients.OnClientHiding = _
Me.AutoCompleteExtenderClients.ClientID + "_OnClientCompleted"
AutoCompleteExtenderClients.OnClientPopulated = _
Me.AutoCompleteExtenderClients.ClientID + "_OnClientPopulated"
AutoCompleteExtenderClients.OnClientItemSelected = _
Me.AutoCompleteExtenderClients.ClientID + "_OnClientItemSelected"
ScriptManager.RegisterClientScriptBlock(Me, Me.GetType(), _
Evento_OnClientPopulating, Me.OnClientPopulating(Evento_OnClientPopulating), False)
ScriptManager.RegisterClientScriptBlock(Me, Me.GetType(), _
Evento_OnClientCompleted, Me.OnClientCompleted(Evento_OnClientCompleted), False)
ScriptManager.RegisterClientScriptBlock(Me, Me.GetType(), _
Evento_OnClientPopulated, Me.OnClientPopulated(Evento_OnClientPopulated), False)
ScriptManager.RegisterClientScriptBlock(Me, Me.GetType(), _
Evento_OnClientItemSelected, Me.OnClientItemSelected(Evento_OnClientItemSelected), False)
End Sub
El control TextBox está asociado con el control AjaxToolKit:AutocompleteExtender y configurado para los web services usando WCF. El control Asp:HiddenField es utilizado para almacenar la entidad serializada seleccionada.
Â
<asp:textbox autocompletetype="Search"
autopostback="false" id="txtClient" maxlength="40"
ontextchanged="txtClient_TextChanged" runat="server"></asp:textbox>
<asp:hiddenfield id="hdnValue"
onvaluechanged="hdnValue_ValueChanged" runat="server">
</asp:hiddenfield>
<ajaxtoolkit:autocompleteextender
completioninterval="3"
completionlistcssclass="completionList"
completionlisthighlighteditemcssclass="itemHighlighted"
completionlistitemcssclass="listItem"
completionsetcount="20"
delimitercharacters=""
enablecaching="false"
firstrowselected="true"
id="AutoCompleteExtenderClients"
minimumprefixlength="1"
runat="server"
servicemethod="GetClientsWCF"
servicepath="~/ServicesWCF/Services.svc"
targetcontrolid="txtClient"
usecontextkey="true">
</ajaxtoolkit:autocompleteextender>
Para buscar los datos en la lista, introduce el parámetro prefixText y luego ejecuta la consulta LINQ. Una vez que la consulta se haya completado, serializa los datos y luego envÃa el Id y el Name al cliente.
Public Function GetClientsWCF(ByVal prefixText As String, ByVal count As Integer, _
ByVal contextKey As String) As IEnumerable(Of Object) Implements IServices.GetClientsWCF
Using ContextUOWork As New DatabaseEntities
Try
Dim AgentesRequest As New ConcurrentBag(Of Object)
ContextUOWork.Database.Connection.Open()
Dim query As List(Of Names) = (From p In ContextUOWork.Names.AsNoTracking _
Where (p.Name.Trim.ToUpper.StartsWith(prefixText.Trim.ToUpper)) _
Take count Order By p.Name Ascending).AsParallel.ToList()
ContextUOWork.Database.Connection.Close()
For Each c As Names In query
AgentesRequest.Add(_json.Serialize(New With { _
Key .Id = c.Id, _
Key .Name = c.Name.Trim.ToUpper()
}))
Next
Return AgentesRequest.Reverse.Cast(Of Object)()
Catch ex As Exception
Throw New Exception("GetClientsWCF")
End Try
End Using
End Function
Los datos se muestran en el cliente mediante la ejecución del código JavaScript creado en el paso 1. Hago el análisis de los datos JSON.parse (list.childNodesi.value) para transformar y ser capaz de leerlos desde el cliente en mi lista.
function Clients_AutoCompleteExtenderClients_OnClientPopulated(sender, e)
{
$('#Clients_txtClient').removeClass('loading');
var list = $find('Clients_AutoCompleteExtenderClients').get_completionList();
var count = list.childNodes.length;
list.childNodes;
for (i = 0; i < count; i++) {
var item = JSON.parse(list.childNodes[i]._value);
var Id = item.Id.toString().rpad('u00a0',10);
var Name = item.Name.toString().rpad('u00a0',50);
list.childNodes [i].innerHTML = Id + Name;};
};
Para seleccionar los datos en la lista, es serializado y almacenado en la variable oculta (Clients_hdnValue), y luego hacemos la devolución de datos al servidor (doPostBack) para ejecutar el evento hdnValueValueChanged.
function Clients_AutoCompleteExtenderClients_OnClientItemSelected(sender, e) {
var selectedAgente = eval('(' + e._value + ')');
$('#Clients_txtClient').val(selectedAgente.Name);
$('#Clients_hdnValue').val(JSON.stringify(selectedAgente));
__doPostBack('Clients_hdnValue', '')
};
Deserializa el valor que está en el campo de tipo HiddenField y dispara el control de eventos ClientSelected() para advertir que se selecciona una entidad.
Protected Sub hdnValue_ValueChanged(sender As Object, e As EventArgs) Handles hdnValue.ValueChanged
NameTyped = New JavaScriptSerializer().Deserialize(Of Object)(DirectCast(sender, HiddenField).Value)
For Each prop As System.Reflection.PropertyInfo In _NamesEF.GetType().GetProperties()
If prop.CanRead Then
For Each pair In NameTyped
If pair.Key.Equals(prop.Name) Then
prop.SetValue(_NamesEF, pair.Value, Nothing)
End If
Next
End If
Next
Me.TBL_NAMES = _NamesEF
RaiseEvent ClientSelected()
End Sub
El formulario WebForm.aspx detecta el evento del crontol (clientes). La propiedad TBLNAMES contiene la entidad seleccionada.
Private Sub Clients_ClientSelected() Handles Clients.ClientSelected
Id1.Text = Me.Clients.TBL_NAMES.Id
Name1.Text = Me.Clients.TBL_NAMES.Name
UpdatePanel_Data.Update()
End Sub
Y este ha sido el tutorial sobre crear un autocompletador con EntityFramework, esperamos que te haya gustado y sepas aplicarlo en tus futuros proyectos. Ya sabes que si nos quieres proponer un tema que quieres ver reflejado como un tutorial o como una práctica, solo tienes que hacer uso del área de comentarios de un poco más abajo. Por el contrario, si quieres enviarnos tus propios tutoriales, puedes hacerlo a través de la intranet de usuarios que está habilitada para ello, a través del menú Enviar Tutorial. Ya sabes, ayúdanos a crecer con tus conocimientos. ¡Un saludo y feliz código!
