jueves, 19 de julio de 2012

Uso de Gráficas en la web

En el desarrollo web, es indispensable el uso de gráficas adecuadas para presentar a los usuarios información relevante, resumida y de gran valor, es por esto que acudimos a muchas opciones que presenta el mercado, y comenzamos a divagar tratando de conocer cual es la más fácil de usar y la más adecuada para nuestras aplicaciones.

He tenido la oportunidad de trabajar con las charts de .net en framework 3.5 y 4, algunas librerias bastante complicadas, y después de probar algunos sin sabores y amplias limitaciones, me presentaron highchart y kendo dos tecnologías basadas en javascript y que definitivamente me han dado excelentes resultados y son gratuitas sin soporte. Los pre-requisitos para sacar mayor provecho a estas tecnologías son POO en JavaScript cuyo concepto difiere un poco al que estamos acostumbrados, conceptos básicos de la estructura de las gráficas. 

Estos son algunas de las cosas que he logrado realizar usando dichas tecnologías (no puedo compartirles el código por cuestiones de contrato), para que se hagan una idea de lo que se puede lograr:
  • Construcción de gráficas dinámicamente o a petición
  • Uso de las dos tecnologías (highchart y kendo) usando un script trabajando como factory
  • Consumo de datos a través de servicios web
  • Actualización de gráficas si recargar la página
Las ventajas son muchas sobre todo en performance de la página y la experiencia de los usuarios. Espero la estudien y les sirva.


highchart  http://www.highcharts.com/demo/dynamic-update
Kendo      http://demos.kendoui.com/dataviz/overview/index.html

jueves, 12 de julio de 2012

Patrones de Diseño JavaScript

Incursionando en este mundo del JavaScript avanzado, quise dejarle a mi actual empresa un semi proyecto en JS orientado a la fábrica de objetos tipo gráfica, con el cual se facilite el trabajo de los demás equipos de desarrollo, además implementando patrones de diseño para darle un toque distintivo para mejoras en el futuro y dejar alguna huella; entonces me encuentro con este pequeño libro donde podemos aprender el uso de este patrón, además de un video explicativo del tema, el cual espero les sirva para mejorar sus práticas de desarrollo.


libro      http://addyosmani.com/resources/essentialjsdesignpatterns/book/
video    http://vimeo.com/44094122

miércoles, 13 de junio de 2012

Failed to load viewstate


Failed to load viewstate.  The control tree into which viewstate is being loaded must match the control tree that was used to save viewstate during the previous request.  For example, when adding controls dynamically, the controls added during a post-back must match the type and position of the controls added during the initial request.


Tuve un encuentro con este caso particular que a simple vista puede generar terror e inconformidad. Mi escenario fue el siguiente: un pagina con un formview y un gridview, cuyo desarrollo me cedieron para realizar algunas modificaciones. En la lógica el formview nunca se muestra en modo itemtemplate, por lo cual sólo realizé los cambios necesarios para el inserttemplate y el edittemplate, esto ocasionaba que por defecto, una vez que se realizaba una actualización, este intentara mostrar en modo readonly, lo cual generaba el error referenciado, entonces hay dos opciones para resolver el problema.

  1. Crear adecuadamente el itemtempleta para que carge los datos correctamente (si es necesario)
  2. Como en mi caso no se usa este template, simplemente cambié el defaultmode a Edit
Soluciones practicas a problemas simples.

martes, 27 de marzo de 2012

Call server methodo from client javascript

Aveces nos veremos obligados a llamar un método que tenemos del lado del servidor, o simplemente no queremos complicarnos en buscar la manera desde el cliente de obtener los datos necesarios para ejecutar el método deseado, para eso tenemos la siguiente de muchas opciones:


Por mensionarlo, tenemos estas opciones:
__doPostBack ==> detallado más adelante
RadAjaxManager ==> nos permite ejecutar el método definido en su "OnAjaxRequest"
ScriptManager  ==> acá una explicación


Explico el "__doPostBack" por su facilidad y efectividad, porque he visto las otras opciones fallar en algún momento.


__doPostBack es una función que genera un postback a nuestra página, el cual podemos capturar en el evento Load de la página.


La estructura del __doPostBack es la siguiente:  __doPostBack("target", "argument");
Usando los parámetros podemos controlar el evento "target" y usar los parametros enviados en el "Argument", de la siguiente manera:


protected void Page_Load(object sender, EventArgs e)
{
 if ((Request["__EVENTTARGET"]!= null) && (Request["__EVENTARGUMENT"]!= null))
     {
   if((Request["__EVENTTARGET"]=="Update")&&(Request["__EVENTARGUMENT"]=="1945"))
       {
          //Ejecutar nuestro código del lado del servidor;
       }
    }
 }

Dobleclick Server Event c# ASP

He venido trabajando en un proyecto web Asp .Net, y para redondear el problema, quería implementar el dobleclick en un listbox, y por otra parte ejecutar un evento del servidor llamado desde javaScript. Enseguida un paso a paso para comenzar a usar estas muy útiles funcionalidades.


La primera nos permite capturar el doble click para un control, para esto adicionamos el evento en el load de la página al control de la siguiente manera:

nuestroControl.Attributes.Add("ondblclick", Page.ClientScript.GetPostBackEventReference( nuestroControl, "EventDblclick"));

GetPostBackEventReference nos devuelve una cadena que se puede utilizar en un evento de cliente para que se produzca una devolución de datos al servidor. El control especificado ("nuestroControl") para controlar la devolución de datos y un argumento de cadena con información adicional sobre el evento definen la cadena de referencia ("EventDblclick").


Ahora al realizar la acción de doble click sobre el control que le hemos adicionado nuestro evento nos hará un postback que vamos a capturar con el siguiente método: 



if (Request["__EVENTARGUMENT"] != null && Request["__EVENTARGUMENT"] == " EventDblclick")
            {
                AddElement();
            }



En el mismo page_load capturamos el Request["__EVENTARGUMENT"], cual si corresponde a la acción de nuestro doble click, en el control que le especificamos, traerá como valor el nombre del evento que le hemos referenciado, para este caso "EventDblclick". Desde aquí podemos manejar el evento según sea necesario, para mi caso se trataba de adicionar lo seleccionado en un listbox para adicionarlo a una caja de texto. En fin hay muchas funcionalidades a mi parecer, por lo cual lo comparto.

domingo, 11 de marzo de 2012

C# .Net Games WinForms Othello, Picas Fijas, Reversi

En mis momentos de ocio y por esa gran pasión que llevo por mi profesión, desarrollé un par de juegos, que eran nuestro entretenimiento cuando eramos niños y mi papá nos compró el tan anhelado "Atari".... era lo máximo !!!. En mi casa con mi hermana recordabamos cuando jugabamos othello, entonces me dió por construir una aplicación para jugar. Si no recuerdan othello o no lo conocen, acá les va una descripción:


Se trata de un juego muy simple, donde hay dos jugadores, blanco y negro, la idea del juego es llenar el tablero de fichas con tu color, esto lo consigues cambiando las fichas de tu contrario, colocando un ficha tuya donde en línea recta hayan fichas de tu enemigo y al final haya otra tuya, en fín no se si sea claro, pero lo intenté.

Les comparto mi juego, creado en vs .Net 2010, para que lo evolucionen a .net remoting, para que aprendan, además tiene muchas cosas muy recursivas.

Calma que eso no es todo, porque también tengo otro juego típico, con el que podemos aprender y enseñar, y se trata del punto fama, o fijas picas, no se que más nombres podrá tener.

Se trata de algo que jugabamos cuando niños, y consistía en que escribias en una hoja un numero de 4 cifras, donde no se podía repetir nungún número, y los demás concursantes hacían lo mismo; la idea era descubrir el número del otro, lanzando número, a alguién, ese alguién te decia cuantos número estaban de los que él tenía eran correctos, y cuantos de esos estaban en la posición adecuada, así hasta descubrir el número.... modestia aparte era muy bueno para eso, pero mi hermana nos jugaba sucio porque nos decia datos no muy ciertos, por lo que me inventé este proyectico para que jugaramos en el pc, y no hubiera oportunidad de fraude.

Entonces les hago entrega de Picas Fijas, tambien creado en .Net 2010. que lo disfruten.



miércoles, 7 de marzo de 2012

Enum string - string (key - value) c#

Este es la solución práctica de un problema no problema, pues podríamos encontrar otras soluciones. Se trata de manejar Enum para estandarizar una lista enumerada, pero con llave "string" y clave "string"; para mi caso se  dió porque siempre me gusta dejar un código ordenado, elegante y entendible, entonces me encontré con un proyecto donde se usaban un listado de actividades, donde cada una de ellas tenía una definición en xml estándar, la cual se usaba de manera constante en muchas partes del código, entonces se me ocurrió buscar una opción de manejar un Enum donde se declarara una sola vez estas actividades y simplemente por el nombre de la actividad, cargar su esquema. 

Entonces, acá tenemos la solución, que aclaró simplemente hice algunos cambios pues no es mi idea y no conozco el autor.

Lo primero es armar nuestro Enum, el cual va a tener la siguiente estructura:


Vemos que cada item tiene la propiedad por encima llamada descripción; En esta etiqueta vamos a ubicar los textos que necesitamos asociar a nuestra llave, para este caso se trata de un esquema XML (ejemplo), el cual necesito cargar cada vez que llame una de estas etiquetas.

Ahora, para obtener la información asociada en la descripción usamos la siguiente función, la cual nos va a devolver la descripción según el valor llave del Enum:


Funciona perfectamente, y nuestro código tendrá una lista estándar y reutilizable. De nuevo les comparto, y espero les sirva, aunque no es un problema, podríamos mejorar mucho nuestro trabajo.


Encontrar elementos dentro de Iframe js

Tuve un problema tratando de encontrar unas imágenes rotas dentro de un iframe, que proviene de un control llamado Datadynamics, pero la solución es muy generica por lo cual la comparto, pues de muchas opción que encontré en Internet casi que ninguna me sirvió, entonces hice una compilación de pruebas y construí algo que al final me solucionó el problema, y como ya es costumbre las comparto con ustedes.


Este ejemplo  corrige algunas imágenes que se cargaron sin el nombre de nuestro sitio, no es un problema común, pero hay partes importantes que podemos rescatar.

function CorregirImagenes()
         <               
            // obtiene el nombre de nuestro sitio
            var path =  '<%=Context.Request.ApplicationPath %>'; 
            // Obtiene el iframe
            var ifReport = document.getElementById('IframeName');
           // obtiene el document del iframe
            var doc =  ifReport.contentDocument || ifReport.contentWindow.document;
           // se usa || debido a que en explorer usa una opción y los demás exploradores usan la otra

           // obtiene el body del iframe
            var iFContent = doc.body; 
           // Hasta este punto ya obtenemos lo que queramos dentro de este Iframe

            // obtiene todas las imágenes dentro del body
            // ya obtenidas las imágenes les hago un proceso de inserción  del nombre del sitio para que las cargue correctamente, entonces una funcioncita por si necesitan hacer inserción de un string dentro de otro            var imagenes = iFContent.getElementsByTagName('img');
               for( i=0; i < imagenes. length; i++)
                <    
                    var imagen = imagenes[i].src;
                    var urlimg = imagen.split("/");
                    // debido a que la url de la imagen viene con "/" (http://localhost/sitio/corehandl**), hacemos un split y buscamos en la posición 4 el nombre del sitio, es decir [3], esto nos devolvería la palabra "sitio", si esto es DIFERENTE a nuestro path "/sitio" (al cual le hacemos un substring para compararlo si el "/"), entonces le añadimos nuestro path.
                    if(urlimg[3] != path.substring(1,path.length))
                     <   
                        var newurl = imagen.substring(0, imagen.indexOf("/CoreHandler")) + path +              imagen.substring(imagen.indexOf("/CoreHandler"), imagen.length);                       
                       
                        imagenes[i].src = newurl;                  
                    >
               >           
            return false;
        >


De nuevo espero a alguien le sirva, y comparta este conocimiento.

martes, 21 de febrero de 2012

ShortCut WebApplication Installer Action

Hoy les comparto la manera de crear desde el Instalador Accesos directos para nuestras Aplicaciones web, usando acciones personalizadas de instalación, para lo cual les expongo las principales consideraciones para lograr configurar nuestro instalador y de paso aprender un poco más de este tema.

como no es tema principal pero es indispensable para nuestro conocimiento, les comparto este blog que les dará una idea si aún no tienen el proyecto de instalación, pero igual hay muchas otros tutoriales googleando.

Comenzaré explicando el contexto del problema:
Tengo una aplicación web Empresarial, la cual quiero que una vez instalada en el cliente, me genere una carpeta con mi producto y dentro de ella un link que me permita acceder a ella directamente. Suena fácil, pero lo cierto es que el cliente puede modificar la ubicación de nuestro producto durante la instalación, por lo cual el acceso directo debe ser creado al momento de la instalación.

Lo primero que haremos será adicionar una carpeta importante en el sistema de archivos de nuestro proyecto de instalación; para acceder le damos click derecho en el proyecto y seleccionamos Ver => Sistema de Archivos. obtendremos algo como esto:


Ahora adicionamos la carpeta que me permitirá acceder desde "Inicio Windows" a nuestro producto. Para esto le damos click derecho en la raiz de nuestro sistema de archivos y seleccionamos la opción "Menu programas de usuario". Dentro  de esta carpeta creamos la carpeta de nuestro producto "PatitoSoft". Es importante que adicionemos algún archivo para que al instalar el producto se cree la carpeta, pues si esta se encuentra vacía, no se va a crear en nuestra lista de programas. (yo usé un link a nuestra página principal).

Ahora vamos al tema de configurar la creación de nuestro acceso directo, para lo que necesitamos adicionar una clase especial para tal acción "INSTALLER CLASS". Esta clase se adiciona en la raiz de nuestro PROYECTO WEB, "NO EN EL INSTALADOR", esta clase nos permite adicionar propio código durante la instalación.

Al cargar la clase obtenemos una función por defecto la cual podemos eliminar y añadimos el siguiente código, que nos va a permitir obtener información de la instalación, la cual nos va a permitir crear nuestro acceso directo:


 El "Context.Parameters" son parametros que debemos capturar antes de lanzar nuestra instalación, definiendolos en nuestro proyecto de instalación de la siguiente manera:

En la nuestra "carpeta de aplicación web" debemos tener asociado el resultado de nuestro proyecto web, entonces vamos a la opción de Acciones personalizadas de este proyecto, dando click derecho en el proyecto de instalación y seleccionamos Ver => Acciones Personalizadas.

En la carpeta instalar, también debemos tener asociado el resultado principal de nuestro proyecto web. Lo seleccionamos y vamos a sus propiedades.

En la propiedad CustomActionData adicionamos lo siguiente: 
/TargetDir="[TARGETDIR]\" /TargetVDir="[TARGETVDIR]" /StartMenuFolder="[StartMenuFolder]\" Esto nos va a permitir obtener los valores desde la clase installer a través del context.parameters. para aprender un poco más de los parametros de contexto, veamos este link

Las líneas de código "System.Diagnostics.Trce.WriteLine", nos permite capturar desde el DebugView los mensajes que le definamos.

Una vez definidas las variables, lo siguiente que hace este código es buscar la carpeta "PatitoSoft\Producto", dentro de archivos de programa, es decir, va a buscar la carpeta de nuestro producto y allí va a crear nuestro acceso directo, en nombre de nuestro directorio virtual y la página que definamos como inicial.

Ahora, ya tenemos un instalador que nos crea un acceso directo a nuestra aplicación web y nos ubica nuestra aplicación entre el directorio de programas disponibles de windows.

Pero el cliente también necesita desinstalar, o llegado un error de instalación debemos hacer RollBack de la creación del acceso directo, para que nuestra desinstalación sea limpia. Para esto usamos los siguientes métodos que harán el trabajo.





Este es el blog que me sirvió de guía para poder resolver el problema de instalación. Espero que sirva de ayuda y sea un poco más claro que el original.


lunes, 6 de febrero de 2012

BATALLA NAVAL .NET REMOTING

Hoy voy a compartirles un proyecto hecho con .Net Remoting, se trata del famoso juego de Batalla Naval. Este proyecto no está terminado del todo, pero todo el core esta hecho y podemos implementarle fácilmente su versión web e integrarla con la windows que es la original, pues su arquitectura permite la comunicación entre las dos plataformas.

Estos son los pantallasos de lo que vana a encontrar, además de una pequeña explicación del código y algunas ideas que plantee para darle un toque distinto a este juego. Es decir que tenemos otras opciones más interesantes para jugar, y claro el código lo comparto con el fin de permitir que otros "curiosos" o a quién le haga falta para un trabajo de la U, aprenda y le aporte un poco.

Mis ataques certeros

Mis ataques fallidos

mis naves

Para adelantarles un poco, y aprovechando la vista, tenemos el área de enemigos, de estado y de vista de ataques, además de un pequeño chat para adicionarle un toque de realismo al asunto y crear expectativa en tus ataques.  Por cuestiones de tiempo no lo terminé, pero la idea es tener dos tipos de juegos, uno por grupos y otro individual "todos contra todos". Es decir que la primera opción seria unirme a un grupo y la segunda es el juego normal, pero con muchos enemigos.

Este es el documento del juego, aquí encontraran una explicación un poco mejor de lo que se esperaba, además les comparto el código en el siguiente link (vs 2010 c#).

Espero lo disfruten, aprendan y enseñen con este material.



jueves, 2 de febrero de 2012

Compiler Error Message: CS0433

Este error "CS0433" se presenta al publicar un proyecto en nuestro IIS, y se debe a que al publicar algunas referencias se quedan pegadas y si le sumamos a esto que hicimos algún cambio de referencias, posiblemente obtendremos que al publicar la aplicación esta se encuentre con más de una referencia para un mismo ensamblado. Entonces llegan las dudas y las soluciones sacadas de películas de terror.

Me dí cuenta que en el bin de mi proyecto, me referenciaba los mismos ensamblados pero con las versiones anteriores, es decir los mismos antes de cambiarlos, entonces borré el bin y generé una vez más, pero eso no sirvió de nada. La solución es muy sencilla, me fuí al IIS y borré el sitio, luego en mi proyecto le dí la opción en propiedades del proyecto de generar carpeta para el sitio, y compilé una vez más!!!.   y perfecto, soluciones tontas para problemas estúpidos.

//Espero les sirva...


martes, 31 de enero de 2012

Registrar Assemblies en Global Cache desde instalador


Me he encontrado con un problema muy simpático, al generar un instalador con un componente adicional en ClickOnce. Resulta que proyecto publicado necesita de unas librerías que necesitan estar registradas en la GAC, entonces pueda que necesitemos que nuestro instalador nos ayude un poco con esto, ya que no le vamos a explicar a un cliente que él debe registrar estos ensamblados manualmente, eso para ellos es como pedirle a un niño resuelva el problema de movilidad de Bogota (Colombia). pues bien, estos son los pasos.

Una vez creado el instalador (sino lo han creado este ejemplo les puede servir) debemos acceder al sistema de archivos, para esto le damos click derecho sobre el proyecto y seleccionamos ver -> sistema de archivos.

Ahora vamos a ver las carpetas por defecto de nuestro instalador:



En la raiz de nuestro sistema de archivos le damos click derecho e incluimos una carpeta especial, para este caso, adicionamos la "carpeta cache de ensamblados global", la cual nos va a permitir que adicionemos aquellos asemmblies que deben registrarse en la GAC.

Espero les sirva de apoyo.

Si quieren saber un poco más

jueves, 26 de enero de 2012

error MSB3321, Error importing key

Despues de un par de días luchando contra este desconcertante error, y muchas horas destinadas a nuestro amigo Google, no puede encontrar solución que me sirviera. Al parecer este error es un gran monstruo que no se ha logrado descifrar, y si han llegado hasta acá se darán cuenta.


Si han recibido el popup con el mensaje "Object already exists" y luego "Importing key file "*****.pfx" was canceled", puede que esto les ayude.


Estuve considerando que este problema se debe a algún error que cometí en mi proyecto aunque aún no lo sé, en cuanto a resolverlo converse con algunos de mis compañeros y probamos mil y una cosa, pero al final, probé sobre un proyecto nuevo, con la misma firma digital que me generaba tantos inconvenientes y funcionó perfecto. ¿Entonces porque no probar en mi proyecto, haciendolo desde cero?, ¿Quizas hay algo más que no no se puede ver?. Entonces me puse a la tarea de crear un nuevo proyecto, "copiar y pegar", las clases, formularios, y hacer las respectivas referencias. Entonces probar y EUREKA!!!. El proyecto corrió normalmente y se publicó todo perfectamente.


Espero esta ayuda que me hizo falta durante 3 largos días les funcione.