Introducción a la programación con XNA 3.1 y C#

Jueves, 04 Mar, 2010 @ 14:16 | Por Gustavo Cantero (The Wolf) | XNA

XNAXNA es un conjunto de herramientas y librerías de Microsoft que facilita el desarrollo de videojuegos para PC, XBOX y Zune, y cada vez está siendo utilizado más por estudiantes y principiantes para aprender a programar utilizando C# como lenguaje.

A Simple Introduction to Game Programming With C# and XNA 3.1 En el libro “A Simple Introduction to Game Programming With C# and XNA 3.1″ se explica como desarrollar videojuegos a aquellos que no tienen ningún conocimiento de programación, enfocado en los conceptos y fundamentos de XNA.

A quien le interese puede descargar gratuitamente de http://www.lulu.com/product/download/a-simple-introduction-to-game-programming-with-c%23-and-xna-31/5438606 o, si lo prefieren, pueden consultarlo y leerlo on-line en http://xnagamemaking.com. Si prefieren tener el libro “físico”, pueden comprarlo en http://www.lulu.com/content/7658212.

El centro de desarrollo de XNA pueden encontrarlo en http://msdn.microsoft.com/es-ar/aa937791.aspx y pueden descargar el XNA Game Studio 3.1, su documentación y otras herramientas de http://creators.xna.com/es-ar/downloads

VN:F [1.7.3_972]
Rating: 7.5/10 (2 votes cast)

Traductor gratuito de recursos de .NET

Jueves, 14 Ene, 2010 @ 02:25 | Por Gustavo Cantero (The Wolf) | .NET Framework

Scientia® Resource TranslatorEn Scientia® Soluciones Informáticas desarrollamos una aplicación sencilla pero muy útil utilizando los servicios de traducción que ofrece BingTM: creamos un traductor de recursos de .NET. La idea es muy sencilla, abre un archivo de recursos seleccionado por el usuario (un archivo .resx) y crea los archivos de recursos en los idiomas requeridos. Por ejemplo, podemos tomar un recurso con textos en español y crear los archivos con los textos en inglés, portugués, japonés y tailandés.

Cabe mencionar que este software lo creamos sin fines de lucro, o sea, para utilizarlo y distribuirlo gratuitamente.

A continuación les dejo una captura de la pantalla:

Ventana del Scientia® Resource Translator

A modo de prueba traducimos los textos de la misma aplicación, y ahora soporta más de 20 culturas, lo cual se puede visualizar en el menú de selección de idioma:

Menú de idiomas del Scientia® Resource Translator

Para quien desee utilizarlo o probarlo lo invito a descargarlo de la página de nuestra empresa: http://www.scientia.com.ar/descargas.aspx

Espero que esta herramienta les sea de utilidad.

VN:F [1.7.3_972]
Rating: 1.0/10 (1 vote cast)

Transacciones y modos de aislamiento en SQL Server y .NET

Viernes, 03 Abr, 2009 @ 12:20 | Por Dario Krapp | .NET, General, SQL Server

Comencemos por definir que es una transacción dentro del contexto de SQL Server, una transacción es un conjunto de operaciones Transact SQL que se ejecutan como un único bloque, si alguna operación falla, el bloque completo falla, si todas las modificaciones de los datos realizadas en la transacción tienen éxito, la misma se confirma y el conjunto de modificaciones se hacen permanentes en la base de datos.
Existen tres tipos de transacciones, las transacciones por procedimiento almacenado, las transacciones iniciadas por el cliente y las transacciones COM+ (de las cuales no hablaremos en este artículo).
Las transacciones por procedimiento almacenado tienen lugar en el motor de base de datos mientras que las iniciadas por el cliente tienen lugar en el código, para nuestro caso código .NET. En ambas circunstancias se emplea una estructura similar para el manejo de transacciones:

-- INICIO DE TRANSACCION
-- Comandos
-- ..
-- ...
-- ......
-- SI HUBO ALGUN ERROR CANCELACION DE TRANSACCION
-- SI NO HUBO ERRORES, CONFIRMACION DE TRANSACCION


En el motor de base de datos SQLServer 2005 o 2008, este esquema tomará la siguiente forma

BEGIN TRAN
BEGIN TRY
 Comandos
 ..
 ...
 ......
 COMMIT TRAN
END TRY
BEGIN CATCH
 ROLLBACK TRAN
END CATCH



En versiones previas de SQL Server los comandos de capturas de excepciones (BEGIN TRY, END CATCH, etc.) no se encuentran disponibles, pero existe en cambio la variable @@ERROR (también disponible en versiones posteriores) que puede consultarse luego de cada instrucción para saber si el comando se ejecutó exitosamente.
Desde .NET, empleando clases ADO.NET, el esquema sería el siguiente:

SqlConnection objMyConnection = new SqlConnection(strCnString);
SqlCommand objMyCommand = new SqlCommand(".....");
SqlTransaction objMyTransaction = null;
objMyCommand.CommandType = CommandType.Text;
objMyCommand.Connection = objMyConnection;
objMyConnection.Open();
objMyTransaction = objMyConnection.BeginTransaction(IsolationLevel.ReadUncommitted);
objMyCommand.Transaction = objMyTransaction;
try
{
 //comandos através de objMyCommand
 objMyTransaction.Commit();
}
catch
{
 objMyTransaction.Rollback();
}
finally
{
 objMyConnection.close();
}



Ambos esquemas son semánticamente idénticos. Un punto a considerar es que siempre es preferible que las transacciones se manejen desde el propio motor, ya que se evita el overhead adicional de la transferencia de datos, aunque esta posibilidad no es siempre factible.
Lo más interesante de las transacciones es la concurrencia, y una pregunta frecuente, al menos me parece que lo es, es ¿qué pasa con los datos dentro de una transacción cuando hay concurrencia sobre esos datos?, ¿qué sucede si una transacción modifica datos que aún no ha confirmado y otra transacción lee esos mismos datos en ese momento? ¿Existe una forma de aislar las transacciones para que no haya interferencia entre ellas?, ¿ese aislamiento podrá traer otras consecuencias?. Esos son los puntos que intentaremos recorrer en este articulo, contestando inmediatamente a las primeras preguntas que ya hemos formulado, y la respuesta es (como era de suponerse), si, existe una forma de aislar las transacciones, en realidad existe todo un abanico de posibilidades, conocido como “modos de aislamiento” o “isolation modes”.

Quizás la idea más intuitiva es esperar que no exista ningún tipo de interferencia de datos entre las transacciones, o sea, que cada una sea totalmente aislada de las otras, esto sería esperar que los datos modificados, (inserts, updates, deletes) sean vistos luego de la confirmación, por ejemplo si dentro de una transacción se borran mil registros, y otra transacción lee esos registros en el intervalo de tiempo existente luego del borrado, pero antes de la confirmación, la segunda transacción no debería ver esos registros, ya que si los viera la información sería inconsistente.
Para que esto funcione de esta forma, la segunda transacción debería esperar a que la primera termine de ejecutarse (obviamente si es que la segunda va a leer datos que la primera modificó) ya que es la única manera de asegurarse que los datos estuvisen siendo leídos luego del commit.

La idea no es nada nueva y es conocida como Read Commited y aunque funciona parece que el hecho de que las transacciones deban esperarse entre sí cuando hay cambios en los datos puede ocasionar problemas a medida que la concurrencia vaya incrementándose, no es difícil imaginarse que algunas transacciones recibirán un timeout cuando la concurrencia se incremente.

Una forma rápida de probar como funciona este esquema es crear desde el Visual Studio un método que abra una transacción y ejecute algún comando de modificación sobre una tabla (insert, update o delete), teniendo el cuidado de dejar un break en la línea de código del commit, al ejecutarse el código se abrirá una primera transacción de modificación de datos no confirmada en el servidor SQL Server. Puede entonces desde el Microsoft SQL Server Management Studio abrirse una segunda transacción y ejecutarse una sentencia de consulta de datos sobre la misma tabla (claro está que debe leer datos que hayan sido modificados por la primer transacción) . Veremos entonces que nuestra consulta en el Microsoft SQL Server Management Studio se queda en espera hasta que la línea commit en nuestro proyecto de Visual Studio es ejecutada, si no ocurre un timeout antes.

Transaccion Read Commited VS-MSSMS

un detalle a considerar es que, si una transacción update no modifica los valores de un registro (ya que los valores originales y los nuevos son iguales), el registro no se bloqueará.

Existe otro esquema de trabajo totalmente opuesto, su nombre es inevitablemente Read Uncommited, en este modo de aislamiento pasa todo lo contrario, las transacciones pueden leer los cambios de otras transacciones aunque las mismas aún no se hayan confirmado, pero estarán leyendo datos no confirmados, en este esquema no se producen los bloqueos que se daban en el caso anterior, si hacemos la misma prueba que en el caso previo, pero abriendo la transacción en el Microsoft SQL Server Management Studio como Read Uncommited (Reemplazar SET TRANSACTION ISOLATION LEVEL READ COMMITTED por SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED) veremos que no hay bloqueos y los datos son devueltos inmediatamente.
Quizás ya no se generen problemas de concurrencia, debido a que no hay bloqueos, pero es de esperarse que algo malo pueda suceder, y la frase anterior “pero estará leyendo datos no confirmados” es un indicio, las transacciones Read Uncommited leen los datos que aún no han sido confirmados, pero entonces que pasará si esos datos se cancelan con un Rollback, lo que sucede es que la transacción Read Uncommited leerá datos inválidos, este comportamiento de las transacciones Read Uncommited es conocido como Dirty Read literalmente “Lectura Sucia”, Los bloqueos en las transacciones Read Commited evitan justamente este problema.

Por todo lo visto hasta ahora no faltará quien pueda deducir que entonces las transacciones Read Commited son una mejor opción, ya que, si bien pueden bloquearse entre sí, no hay problemas en la lectura de datos. Quizás este modo de aislamiento sea una mejor opción en la mayoría de los casos, y de hecho es el modo de funcionamiento que traen las transacciones por defecto en SQL Server, pero las transacciones Read Commited pueden ocultar una sorpresa, lo cual no suele ser nada grato en ningún caso imaginable, al menos para mí, y las transacciones en SQL Server no son la exepción, solo debemos preguntarnos ¿Qué sucederá si mientras una transacción Read Commited está leyendo datos, una segunda transacción, supongamos también Read Commited modifica datos, digamos que hace updates, deletes e inserts y los confirma?, claro está que si bien nos aseguramos de no leer datos basura gracias a la espera del commit, de todas formas tendremos problemas, ya que algunos de los datos leídos podrían haberse eliminado, podrían también haberse agregado y modificado otros nuevos y la primera transacción ni se enteraría.
A las filas eliminadas, que aunque la primera transacción ve ya no existen, se las conoce como filas fantasma (phantom rows). Un efecto del escenario planteado es que si la primer transacción vuelve a leer los datos (luego que la segunda ya haya confirmado la transacción) aunque la consulta sea idéntica se obtendrán distintos resultados.
Debido a las filas fantasma (eliminadas) y a las filas actualizadas, no es posible garantizar que dos lecturas consecutivas devuelvan el mismo resultado, esto se lo conoce como “lecturas irrepetibles”, claro está que este problema surge porque las transacciones Read Commited le permiten a otras transacciones modificar datos que ellas ya han leído, recordemos que las transacciones Read Commited a lo sumo se bloquean ellas mismas cuando intentan leer datos modificados, pero no bloquean otras transacciones.

Para resolver estos problemas, existen otros modos de aislamientos aún más restrictivos que Read Commited. El modo de aislamiento Repeteable Read (Lecturas repetibles) permite, como su nombre da a imaginar, resolver el problema de las lecturas irrepetibles, ya que no le permite a otras transacciones eliminar o modificar filas leídas por la transacción actual hasta que la misma haya confirmado los cambios, otras transacciones si podrán agregar nuevos datos, se puede entender al Modo Repeteable Read como el modo Read Commited más la restricción a otras transacciones de eliminar o modificar los datos leídos por la primera, en este caso las transacciones Repeteable Read bloquean además otras transacciones para no permitirles modificar datos que ellas han leído.

Finalmente existe un nivel aislamiento aún más restrictivo que los anteriores conocido como Serializable, este nivel de aislamiento se comporta como el modo Repeteable Read, pero además tampoco le permite a otras transacciones agregar datos, en consecuencia cada transacción se ejecuta en serie una tras otra sin ninguna posibilidad de realización de tareas en paralelo.
Hasta el momento es claro que a un mayor nivel de aislamiento le corresponderá un mayor bloqueo de registros, en consecuencia, una menor escalabilidad.

SQL Server 2005, trajo un nuevo modo de aislamiento conocido como Snapshot, la idea de este modo de aislamiento es que una transacción pueda leer datos sin la posibilidad que se produzcan dirty reads, pero sin establecer bloqueos, o sea, una solución con la estabilidad de un Read Commited pero con los bloqueos de un Read Uncommited, para poder utilizar este modo de aislamiento, a diferencia de los anteriores hay que establecer en la base de datos lo siguiente:

ALTER DATABASE ... SET ALLOW_SNAPSHOT_ISOLATION ON

Desde ese momento todas las transacciones establecidas como snapshot emplearán este nivel de aislamiento, si se desea que este modo sea el modo por defecto y ya no ReadCommited, debe ejecutarse el comando:

ALTER DATABASE ... SET READ_COMMITTED_SNAPSHOT ON

El modo de aislamiento Snapshot mantiene las versiones de los cambios en la base de datos tempdb para cada transacción, cuando una transacción toma datos, los mismos poseen asociado un numero de versión, para que la confirmación tenga éxito es requisito que los datos a modificar no posean un número de versión mayor al que posee la transacción. Si una transacción intenta confirmar datos con una versión de cambios anterior a la actual, la operación fallará.

Un último comentario sobre este modo de aislamiento es que emplea un esquema optimista. En un esquema optimista se espera que la concurrencia a los mismos datos desde varias transacciones sea poco frecuente, por eso no es muy problemático devolver un error cuando se dá dicha situación. En cambio en el enfoque pesimista se espera que haya mucha concurrencia a los mismos datos y por tal motivo se emplean mecanismos de bloqueo para poder evitar el problema. En las aplicaciones donde se espera que una gran cantidad de usuarios concurrentes, por ejemplo las aplicaciones web tan en auje actualmente, la idea de bloquear registros parece cada vez menos atrayente, por eso el enfoque optimista parece haber tomado popularidad, En LINQ para SQL, como tecnología de punta en acceso a datos, no solo se considera el esquema optimista, sino que además de emplearlo como modo de concurrencia por defecto, posee ya incorporadas metodologías reajustar los datos en el caso de fallas por acceso a datos concurrentes, quien esté interesado y aún no haya podido ver nada del tema, puede esperar a que escribamos algún artículo o adelantarse a buscar info de esta tecnología, un tip para los segundos : RefreshMode.KeepChanges y espero como siempre, que este artículo haya sido de utilidad.

VN:F [1.7.3_972]
Rating: 9.2/10 (13 votes cast)

Conversiones de colores en .NET

Jueves, 13 Nov, 2008 @ 18:22 | Por Gustavo Cantero (The Wolf) | .NET

Muchas veces estamos trabajando con colores en .NET y necesitamos obtener el código HTML de los mismos para utilizarlo en un control, o el número correspondiente al color Ole para pasárselo a un componente COM (ActiveX).  El primer caso puede resolverse obteniendo cada componente RGB del color y pasando su valor numérico a hexadecimal, pero para convertirlo a Ole para utilizarlo en COM es más complicado.  Para resolver estas cuestiones en .NET existe la clase ColorTranslator, la cual se encuentra en el namespace System.Drawing, y permite convertir un color de .NET a HTML, Ole o Win32 y viceversa, o sea, de un valor entero de un color Ole o de Windows o de un string con un color HTML se puede obtener el color en .NET correspondiente.  Un ejemplo de esto se muetra en la siguientes lineas:

string strBlanco = "#FFFFFF"; //Blanco
string strRojo = "#FF0000"; //Rojo
 
//Estructura de .NET con el color blanco
System.Drawing.Color colorBlanco = System.Drawing.ColorTranslator.FromHtml(strBlanco);

//Estructura de .NET con el color blanco
System.Drawing.Color colorRojo = System.Drawing.ColorTranslator.FromHtml(strRojo);

//Valor numérico que representa el color blanco en Windows
int intBlanco = System.Drawing.ColorTranslator.ToWin32(colorBlanco);

//Valor numérico que representa el color rojo en Ole
int intRojo = System.Drawing.ColorTranslator.ToOle(colorRojo);

VN:F [1.7.3_972]
Rating: 8.0/10 (1 vote cast)

Ya salió la versión RTM de Silverlight 2.0

Viernes, 17 Oct, 2008 @ 13:16 | Por Gustavo Cantero (The Wolf) | Silverlight

El 13 de Octubre Microsoft anunció, a través de un comunicado de prensa, la versión RTM de Silverlight 2.0, la cual está disponible para descargarse desde el 14 de octubre desde la página de Silverlight.

Como novedad para los diseñadores, el Microsoft Blend 2.5 (que aún no estaba en su versión final) ahora es un Service Pack para el Microsoft Blend 2.0, o sea, para trabajar con Silverlight 2 solamente hay que instalarle el Service Pack 1 al Blend 2.0.

Para los desarrolladores: antes de instalar el Silverlight 2 tienen que instalar el Service Pack 1 para Visual Studio 2008 o, para la gente que no posee una licencia de Visual Studio 2008, Microsoft extendió el soporte a Visual Web Developer 2008 Express Edition para que también se pueda desarrollar aplicaciones para Silverlight 2 con esta herramienta, la cual es de gratis descarga.

Otra noticia importante es que existe un proyecto Open Source llamado eclipse4SL de Soyatec y Microsoft para poder crear aplicaciones Silverlight desde eclipse, el cual planean tenerlo terminado para la segunda mitad de 2009, aunque ya puede descargarse la versión Milestone 1.

Algunas de las novedades que se muestran en el comunicado de prensa son:

  • Soporte para .NET Framework con una librería de clases enriquecida, la cual es un subconjunto compatible de .NET Framework.
  • Controles potentes, entre los que se incluyen: DataGrid, ListBox, Slider, ScrollViewer, Calendar y más.
  • Suporte de plantillas y skins avanzados, lo que facilita la personalización del “look and feel” de nuestras aplicaciones.
  • Deep zoom. Esto permite tener interactividad y navegación con imágenes de ultra-alta resolución.  Esta tecnología es similar a la utilizada en Virtual Earth y Google Map para ir “bajando” en un mapa hasta llegar cerca del suelo.
  • Amplio soporte para networking, permitiendo hacer llamadas a través de REST, WS*/SOAP, POX, RSS y servicios HTTP estándar, permitiendo crear aplicación que se integren fácilmente a los sistemas existentes.
  • Soporte del lenguaje .NET Framework para varios lenguajes, entre los cuales se incluyen Visual Basic, C#, JavaScript, IronPython y IronRuby.
  • Protección avanzada de contenidos, gracias a Silverlight DRM que utiliza PlayReady.
  • Mejora en la escalabilidad, utilizando capacidades de streaming y descarga progresiva, técnicas de búsqueda avanzadas, y soporte para “in-stream advertising”.
  • Soporte multi-plataforma y multi-navegador, con soporte para Mac, Windows y Linux en Firefox, Safari e Internet Explorer.

Como último comentario cabe mencionar que la adopción de Silverlight sigue creciendo, con una penetración cerca del 50% en algunos países, y teniendo decenas de miles de aplicaciones desarrolladas con esta tecnología.  Durante los 17 días de los juegos olímpicos de Beijing el sitio NBColympics.com, el cual utiliza tecnología Silverlight, tuvo más de 50 millones de visitantes, con 1.3 mil millones de páginas visitadas, 70 millones de streams de videos y 600 millones de minutos de video vistos.

A continuación dejo algunos enlaces de utilidad:

Sin duda es una buena noticia para la comunidad desarrolladora.

VN:F [1.7.3_972]
Rating: 7.0/10 (1 vote cast)

Eliminar archivos temporales de ASP.NET

Jueves, 18 Sep, 2008 @ 12:10 | Por Gustavo Cantero (The Wolf) | .NET, ASP.NET, IIS

Cuando accedemos por primera vez a una aplicacion web hecha con .NET el IIS compila las páginas y guarda los assemblies generados (junto con los de la carpeta bin) en una carpeta temporal de cache, la cual está en el mismo lugar donde se instala el framework.  Rara vez sucede que el IIS no refresca esta cache, y cuando actualizamos nuestras páginas o assemblies, éstas no se ven reflejadas.  Para asegurarnos que esta actualización suceda debemos limpiar esta cache, y para hacerlo debemos seguir los siguientes pasos:

  • Detener el IIS, lo cual se puede hacer con el comando "IISReset /stop"
  • Eliminar el contenido de la carpeta “C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files”
  • Iniciar nuevamente el IIS, lo cual se puede hacer con el comando "IISReset"

Luego de esto, al ingresar en nuestra aplicación, el IIS vuelve a compilar el sitio y generar los archivos de cache.

VN:F [1.7.3_972]
Rating: 9.9/10 (7 votes cast)

Deshabilitar controles de la página hasta que finalicen los UpdatePanels

Jueves, 19 Jun, 2008 @ 00:30 | Por Gustavo Cantero (The Wolf) | AJAX, ASP.NET

Hace unos meses comenzamos a desarrollar para un cliente una aplicación web más o menos compleja, con .NET 3.5 y bastante uso de AJAX. En esta aplicación hay páginas que utilizan varios UpdatePanels, y algunos de estos realizan procesos complejos que pueden llegar a demorar varios segundos, es por esto que nuestro cliente nos pidió que, al iniciar estos procesos, se bloquee la página para que el usuario no pueda ejecutar ninguna otra acción en la misma hasta tanto no finalice el proceso pendiente.  Obviamente no queríamos ejecutar un script “a mano” cada vez que se ejecutaba una acción y otro al finalizar la misma, así que buscamos la manera de automatizarlo un poco.  Comenzamos buscando los eventos propios del motor de AJAX de Microsoft® y encontramos que podemos capturar los del RequestManager cuando inicia una petición al servidor y cuando la misma finaliza.  Esto lo podemos hacer utilizando los métodos add_initializeRequest y add_endRequest de la instancia actual del PageRequestManager, la cual podemos obtener con el siguiente código: Sys.WebForms.PageRequestManager.getInstance().
En el primer evento mostrábamos un ModalPopUp (control que muestra una “ventana” en la página y deshabilita todos los demás controles de la misma) de la librería ASP.NET AJAX Control Toolkit de Microsoft®, el cual contenía un mensaje que decía “Aguarde un momento…”, y en el segundo evento lo cerrábamos.  A continuación se muestra como quedaba el PopUp en la página:

<cc1:ModalPopupExtender ID="mpeLoading" runat="server" BehaviorID="idmpeLoading" PopupControlID="pnlLoading" TargetControlID="btnLoading" EnableViewState="false" DropShadow="true" BackgroundCssClass="ModalBackground" />
<asp:Panel ID="pnlLoading" runat="server" Width="300" Height="50" HorizontalAlign="Center" CssClass="ModalPopup" EnableViewState="false" Style="display: none">
<br />Aguarde un momento...</asp:Panel>
<asp:Button ID="btnLoading" runat="server" Style="display: none" />

y acá está el código JavaScript:

function initializeRequest(sender, args){
    $find('idmpeLoading').show();
}
function endRequest(sender, args){
    $find('idmpeLoading').hide();
}
Sys.WebForms.PageRequestManager.getInstance().add_initializeRequest(initializeRequest);
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(endRequest);

Cabe aclarar que la variable idmpeLoading del código anterior contiene el identificador del ModalPopUp a mostrar.
Hasta este punto todo funcionaba bien, el problema surgió cuando utilizamos paneles modales con UpdatePanels dentro, en ese momento la ventana con el mensaje “Aguarde un momento…” se “dibujaba” debajo del panel que estaba utilizando el usuario, no cumpliendo con su finalidad, ya que de esta manera no se deshabilitaban todos los controles de la página.
Paso siguiente revisamos el código del ModalPopUp (el mismo se puede bajar desde el mismo link que mostré antes) y encontramos que a los paneles se les estable un valor fijo en el estilo zIndex para mostrarlos sobre los demás controles.  Luego revisamos las propiedades del objeto de JavaScript que representa el panel y encontramos que posee dos objetos interesantes: _backgroundElement y _foregroundElement.  Estos representan los DIVs del fondo y del contenido de PopUp respectivamente, entonces para hacer que estos objetos de HTML se posicionen sobre todos los demás simplemente tenemos que incrementarles la propiedad zIndex de su estilo.  Entonces, nuestro código JavaScript queda como se muestra a continuación:

function initializeRequest(sender, args){
    var mpeLoading = $find(idmpeLoading);
    mpeLoading.show();
    mpeLoading._backgroundElement.style.zIndex += 10;
    mpeLoading._foregroundElement.style.zIndex += 10;
}
function endRequest(sender, args){
    $find(idmpeLoading).hide();
}
Sys.WebForms.PageRequestManager.getInstance().add_initializeRequest(initializeRequest);
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(endRequest);

Por último, para hacer que esta funcionalidad esté presente en todas las páginas de nuestra aplicación, lo agregamos en la página “master” del sitio, logrando que en cualquier página (que utilice esta master) posea la funcionalidad aquí descripta.

En la siguiente imagen muestro como queda una aplicación de ejemplo que cree con Visual Studio 2008 para este artículo:

A continuación dejo el proyecto con el código fuente para quien quiera utilizar esta utilidad:

Gustavo Cantero (The Wolf)
MCP – MCSD – MCTS

VN:F [1.7.3_972]
Rating: 8.0/10 (4 votes cast)

Acerca de nosotros

Miércoles, 11 Jun, 2008 @ 20:42 | Por Gustavo Cantero (The Wolf) | General

Programando a medianoche

Programando a medianoche es sin ninguna duda algo que a cualquier programador le debe resultar conocido, ya que… ¿Qué programador no se ha quedado noches enteras tratando de resolver un problema que parecía imposible por puro placer?  ¿Qué programador no se ha quedado noches enteras tratando de resolver un problema porque al día siguiente había una entrega impostergable?  ¿O incluso por alguna otra causa?  Por ese motivo éste blog toma ese nombre, intentando poder proveer una ayuda por más pequeña que sea para resolver ese problema. Para que algún otro programador pueda alegrarse de haber encontrado una ayuda a algún problema que no lo dejaba pensar en otra cosa o para que algún otro programador pueda terminar con su entrega e irse a dormir un rato antes.

Quienes somos

Hola.  Me llamo Gustavo Cantero, vivo en Buenos Aires, Argentina, con mi esposa e hijas y trabajo en Scientia Soluciones Informáticas, una empresa de consultoría informática y desarrollo de software y programación web que, junto con Darío Krapp, fundamos a fines de 2007. Mi experiencia con las computadoras comenzó en la década del 80, con mi primer ordenador: el ZX Spectrum.  Pese a que el mismo tenía una escasa memoria de 48 Kb y como lenguaje un BASIC muy reducido, tengo muy buenos recuerdos de los programas que creaba en él cuando aún no cumplía mis 10 años.  Ya a los 17 años conseguí mi primer empleo como programador y desde ese momento, y hasta ahora, he utilizado varias tecnologías y desarrollado en distintos lenguajes con variadas herramientas, entre los cuales se encuentran COBOL, Clipper, FoxPro, QuickBasic, Visual FoxPro, Visual Basic, ASP con VBScript, GeneXus, Visual Basic .NET, C# y C.  Desde el primer momento que tuve contacto con una computadora (hace unos 24 años) y hasta este momento hay algo que nunca cambió: me apasiona la tecnología y trato de entenderla y utilizar lo mejor que pueda.

Yo soy Darío Krapp y como era de esperarse también trabajo en Scientia Soluciones Informáticas.
Mi primer contacto con una computadora fue a fines de los 80 con una Commodore 64 con Datassette, mezclando juegos con los primeros programas.   La programación en aquellos tiempos tenía muchas restricciones, si la comparamos con la actualidad, pero uno no lo sabía entonces y de todas formas no dejaba de ser divertido y didáctico.
Desde aquellas lejanas épocas de Basic V2, de gosub’s, poke’s, peek’s y otras cosas de ese tipo hasta hoy han pasado una cantidad incontable de tecnologías y lenguajes, algunos de los que recuerdo son Pascal,  C,  Visual Basic,  ASP,  Visual Basic .NET,  C#,  GeneXus y algunos no tan conocidos como Basic 4690 y C 4690, para hablar sólo de los lenguajes, una historia que supongo que debe repetirse con cada programador. Pero creo que a pesar de la diversidad de tecnologías, algunas más atrayentes que otras, siempre hay una constante, que es la necesidad incontrolable de aprender, de resolver, de innovar, y de mejorar, eso que puede llevarnos a pasar una madrugada entera tratando de resolver un problema o de mejorarlo.  Creo que esa constante es lo permite que la tecnología avance día a día.

Que escribiremos

En este blog escribiremos consejos, trucos y código de los desarrollos que hacemos en Scientia® Soluciones Informáticas y que creemos que puede serle útil a cualquier programador que se tope con el mismo problema que nosotros.

Cómo contactarnos

Pueden hacerlo agregando comentarios a los post que hagamos o enviando un correo a blog@scientia.com.ar.

VN:F [1.7.3_972]
Rating: 10.0/10 (1 vote cast)