Este documento resume los principales conceptos del desarrollo con Silverlight 2.0, incluyendo tres modelos de arquitectura, las herramientas Visual Studio 2008 y Expression Blend 2, conceptos de clases, interfaces y soporte, gestión de estado mediante almacenamiento aislado, y la interacción entre Silverlight y HTML.
2. Fundamentos: “Programación en Silverlight 2.0”
de Netalia Ediciones
Primero publicado en
castellano
Versión final (RTW)
Gratuito con el número de
noviembre de
dotNetMania
Accesible desde la Web de
la revista (
www.dotnetmania.com)
Está siendo entregado en
los eventos de desarrollo
de Microsoft.
3. Microsoft Silverlight es un componente
multiplataforma, y multinavegador que
permite la programación en .NET de la
siguiente generation de aplicaciones para
internet: (rich interactive applications ó
R.I.A.)
4. Índice
Arquitectura y buenas prácticas
Modelos de arquitectura y escenarios para el desarrollo
con Silverlight.
Implicaciones del modelo de seguridad en sandbox y el
PAL (Platform Adaptation Layer).
Visual Studio 2008 y Expression Blend 2
El papel de Visual Studio 2008 en el desarrollo con
Silverlight 2.
Arquitecturas de navegación.
Clases, Interfaces y soporte arquitectónico.
Gestión de estado de la aplicación (Almacenamiento Aislado).
Eventos.
Manejo de hebras de ejecución y el componente
BackgroundWorker.
Gestión de recursos.
5. Indice
3. Expression Blend y la interfaz de usuario
Recomendaciones para el diseño.
Controles del SDK y aportaciones del Silverlight Toolkit de Marzo 2009.
Estilos, Plantillas y recursos de diseño.
Visual State Manager.
Enlace con objetos de lógica de negocio.
Comunicaciones fuera del sandbox
Interacción con HTML /DOM y el navegador.
Cajas de Diálogo del sistema y acceso a recursos locales.
Acceso a Servicios: ASMX (SOAP), WCF para Silverlight y REst.
Acceso a datos con ADO.NET Data Services.
Buenas prácticas e instalación de aplicaciones
El decálogo de las buenas prácticas en aplicaciones Silverlight.
El proceso de instalación, desde el punto del cliente y del servidor.
Introducción a los modelos de programación complejos: PRISM
2.0.
8. Arquitectura Silverlight
Framework
Browser Host
Data WPF Networking MS AJAX
Extensible Library
Integrated LIN XLINQ
Q Controls REST POX
Networking
Stack DLR BCL HTML DOM
Generics RSS JSON Integration
Ruby Python Collections
CLR Execution Engine
Application
Services XAML Leyenda
UI Core Inputs DRM V2.0
Keyboard
Media Leyenda
Vector Text Mouse Ink
Installer Animation Media V1.0
Controls
Images
VC1 WMA MP3 Layout Editing
9. Historia Microsoft de Arquitectura N-Tier
En Microsoft, las arquitecturas N-Tier comenzaron con Windows NT 4.0 Option
Pack, (Epoca1998 aprox.)
-Componentes MTS (Microsoft Transaction Server) C++/VB
-DCOM (Distributed COM)
-Windows DNA(EpocaWindows 2000)
-ComponentesCOM+, C++/VB, etc.
1998
Arquitectura 3-Tier
¡Este diagrama es valido hoy! (2009)
10. Arquitectura N-Tier / .NET 2.0/3.x(2005-2009)
Capa de Presentación
WPF, XBAP, WinForms
ASP.NET, AJAX, ASP.NET MVC
Silverlight
Capa de Negocio
Assemblies(.NET components)
WCF Services / WS .asmx
System.Transactions
Arquitecturas personalizadas
Capa de Datos
Microsoft SQL Server
Otros SGBD (Oracle, DB2, etc.)
11. Arquitectura de Silverlight 2.0
Arquitectura de Silverlight
Aplicaciones RIA
Otras plataformas RIA
Adobe Flash Player, Adobe Flex, Adobe AIR
Plataformas AJAX
JavaFX
Google Gears
Silverlight y los lenguajes
XAML, .NET, Lenguajes dinámicos: IronRuby, IronPyton
XAML: Expression Blend y Visual Studio 2008
Para el resto: Visual Studio 2008 (Blend no dispone de editor .NET)
13. La Sandbox (Caja de arena)
Toda aplicación Silverlight se ejecuta en una de ellas
Conceptualmente similar a la de HTML DOM
Ejecución similar a las páginas HTML –click en una URL
No hay permisos de ejecución
Pero no hay forma de salir de la sandbox
Incluye funcionalidad adicional:
Almacenamiento Offline
Controles para upload de ficheros
Soporte “Cross domain“ (requiere un fichero CrossDomain.xml en el
servidor de destino)
14. El Runtime (CoreCLR)
Está basado en el PAL (Platform Adaptation Layer)
Introduce por primera vez en .NET la ejecución “side-by-side”
Mapea las API’s del sistema en llamadas disponibles desde
Silverlight
Implementa un sistema de seguridad propio, no basado en el CAS
sino en Transparencia de Seguridad (Security Transparency)
El modelo divide el código en 3 clases:
Transparente (Transparent),
Crítico con seguridad (SafeCritical), y
Crítico (CriticalCode).
16. Instalaciones especiales
Previamente, necesitamos las herramientas como dos ficheros separados:
1) Instalador “Silverlight Tools for Visual Studio 2008 SP1”, disponible en la dirección:
http://go.microsoft.com/fwlink/?LinkId=129043
2) Silverlight 2.0 Developer Runtime desde la dirección
http://go.microsoft.com/fwlink/?linkid=129011
Dos opciones de instalación son:
a) Extraer y pegar.
1. Abrir una ventana de comandos (cmd.exe) y navegar a donde esté el
fichero Siverlight_tools.exe.
2. Ejecutar el comando silverlight_tools.exe /x.
3. Una vez descomprimidos los ficheros, volcar en el mismo directorio el
Silverlight 2.0 Developer Runtime y ejecutar SPInstaller.exe.
b) Colocar el Silverlight 2.0 Developer Runtime en el directorio Temp (no requiere
descompresión de ficheros).
1. Navegar al directorio Temp (o abrir una ventana de comandos y teclear la
secuencia: CD %Temp%.
2. Crear desde ahí un directorio para la instalación.
3. Copiar Silverlight.2.0_Developer.exe a ese directorio y ejecutar el
instalador Silverlight_tools.exe.
17. Visual Studio 2008 y Expression Blend 2
Modelos de arquitectura y escenarios para el desarrollo
con Silverlight.
3 Modelos básicos:
“Islas” Silverlight (similares a Flash)
Componentes individuales que pueden coexistir en la
misma página
Aplicaciones de tipo medio con toda la interfaz en Silverlight/
XAML
Aplicaciones de tamaño superior que requieren una
arquitectura más sofisticada: PRISM 2.0
18. Visual Studio 2008 y Expression Blend 2
“Islas” Silverlight (similares a Flash)
El entregable resultante (fichero XAP) debe estar
programado de tal forma que su funcionamiento sea
“Loosely Coupled”
Aunque no siempre es posible del todo
El tratamiento de errores para estos casos especiales se
convierte en exhaustivo.
Los problemas pueden venir de dependencias del DOM,
de acceso a servicios no disponibles, de accesos
“crossdomain”, de insuficiencia de permisos en acceso a
información local de la máquina, etc.
En producción, si nuestro servidor no permite la adición del
tipo MIME .XAP, la solución es renombrarlo a .ZIP (formato
reconocible por todos los servidores)
19. Visual Studio 2008 y Expression Blend 2
Aplicaciones de tipo medio
Toda la interfaz es puro Silverlight
La parte ASP.NET/HTML actúa meramente como contenedor
de las páginas Silverlight
Requiere la codificación de un sistema de navegación propio
Pueden considerarse técnicas más avanzadas a este
propósito, como la IoC (Inversion of Control)
De la misma forma en este modelo y el siguiente
recomiendan a veces técnicas de inyección de
dependencias (Dependency Injection)
Aplicaciones grandes
PRISM 2.0 es el modelo “Patterns & Practices” construido a
tal efecto
Comentaremos algo más sobre este modelo al final del
master
21. El papel de Visual Studio 2008 y Blend 2 en el
desarrollo con Silverlight 2.0
dóneo para todo lo que suponga programación de la
funcionalidad del/los controles
ispone de Intellisense (Expression Blend, no)
o dispone de un diseñador visual pero sí de un “intérprete
visual” de la IU
rogramación del modelo de eventos
reación de clases personalizadas
22. El papel de Visual Studio 2008 y Blend 2 en el
desarrollo con Silverlight 2.0
Requiere de una instalación cuidadosa
VS2008 SP1
Blend 2.0 SP1
Visual Studio Tools for Silverlight
• Incluye el runtime de tiempo de ejecución
• Se actualiza automáticamente a la última versión
disponible
Permite la programación sincronizada
La parte de C#/VB. NET en VS2008
La parte XAML, en Blend 2.0
Los cambios en uno de ellos, se reflejan en el otro
24. Visual Studio 2008 y Expression Blend 2
Navegación (si es aplicable)
Lógica o por página
En el fichero ASPX/HTML, dentro de un elemento
<div>
UserControl ≈ View ó Page
• Página contenedora + Grid (root), hace las
veces de un gestor de navegación que
añade/elimina UserControls (páginas) al Grid
Navegación lógica:
30. Sobre clases, interfaces y soporte
Además de los elementos clásicos de desarrollo hay aspectos
especiales a tener en cuenta debido al modelo de alojamiento
en host HTML que usa SL.
Por un lado: no hay problema en heredar de cualquier clase de
la jeraquía disponible en el CoreCLR
Pero debemos de tener en cuenta que no se trata de un modelo
clásico
Podemos crear elementos “híbridos”, que dispongan de aspectos de
la interfaz de usuario con un comportamiento de lógica de negocio
Heredando directamente de elementos de la IU como UIElement o
FrameworkElement.
Podemos crear elementos de animación como clases separadas que se apliquen
posteriormente a elementos de la IU
31. Sobre clases, interfaces y soporte
Si queremos utilizar propiedades de nuestras clases en XAML, debemos
definirlas como DependencyProperties
Se establece así una correspondencia entre elementos propios del CLR
y otros de XAML
La sintaxis de una declaración de este tipo es como sigue:
private static readonly DependencyProperty TextProperty =
DependencyProperty.Register("Text", typeof(string),
typeof(CajaTextoDNI), null);
// el parámetro null puede ser un valor predeterminado o un callback
public string Text
{
get { return (string)GetValue(TextProperty); }
set { SetValue(TextProperty, value); }
}
32. Sobre clases, interfaces y soporte
Otra alternativa es la implementación del rico
conjunto de interfaces disponible
Siempre permite definir una interfaz visual que será
totalmente distinta tanto en funcionalidad como en
aspecto
Manteniendo los elementos básicos (de donde
heredemos).
En Windows Forms, era complejo y los resultados, dudosos
en calidad de la IU.
33. Sobre clases, interfaces y soporte
La integración con HTML permite soluciones híbridas que
aprovechen lo mejor de ambos mundos y que utilicen
tecnologías actuales como ASP.NET AJAX.
En ocasiones, la mejor solución a un problema pasa por una
acción de este tipo
Como por ejemplo, el control del tamaño del componente en función del tamaño del
navegador.
Hay que tener en cuenta que aunque el nivel de cumplimiento de los estándares por
parte de los navegadores se ha incrementado mucho, todavía hay ciertas formas distintas
de dar solución al mismo problema.
El soporte de navegadores es múltiple de verdad:
Windows: IE, Firefox, Safari, Opera, Chrome
Mac: Konqueror, Firefox, Safari
Linux: Varios (a través del proyecto MoonLight)
Para estar seguro, no fiarse, probar la misma página en cada uno de ellos.
34. Sobre clases, interfaces y soporte:
Interacción HTML
Ejemplo básico de esta interacción: Capturar el tamaño del
navegador cuando cambie.
Vincular un manejador del evento resized para el objeto
App.Current.Host.Content.
Page.xaml.cs:
public Page(){
InitializeComponent();
App.Current.Host.Content.Resized += new
EventHandler(Content_Resized);}
Captura el tamaño
void Content_Resized(object sender, EventArgs e) {
double height = App.Current.Host.Content.ActualHeight;
double width = App.Current.Host.Content.ActualWidth;
}
36. Gestión de estado: Almacenamiento Aislado
(Isolated Storage)
Silverlight usa Isolated Storage como sistema
virtual de ficheros para almacenar datos en
una carpeta oculta en la máquina cliente.
Separa los datos en dos secciones:
Sección #1 contiene información administrativa,
como la cuota de disco
Sección #2 contiene los datos en sí. Cada aplicación
Silverlight recibe su parte de almacenamiento
correspondiente que, por defecto, es de 1 MB por
aplicación.
37. Gestión de estado: Almacenamiento Aislado
Ventajas:
Buena alternativa al uso de cookies especialmente
si se trabaja con conjuntos grandes de datos.
Casos típicos incluyen la funcionalidad “undo”,
elementos del carrito de la compra, configuración del
sistema y/o preferencias de usuario.
Isolated storage se almacena por usuario individual
Con permisos suficientes, los clientes pueden
solicitar el incremento de la cuota mediante código
38. Gestión de estado: Almacenamiento Aislado
Posibles inconvenientes:
Los administradores tienen control sobre la cuota, por lo que
pódría producirse un error de acceso, y se precisa el control de
errores.
Con algo de esfuerzo se pueden encontrar los datos y borrar
su contenido. Para prevenir cambios, podríamos utilizar las
clases de criptografía.
El codigo debe tener el permiso IsolatedStorageFilePermission
para almacenar con Isolated Storage.
39. Gestión de estado: Almacenamiento Aislado
ara usarlo, añadimos una referencia using al namespace System.IO.IsolatedStorage, y
otra a System.IO.
sing System.IO.IsolatedStorage;
sing System.IO;
rivate void SaveData(string data, string fileName)
{
using (IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication())
{
using (IsolatedStorageFileStream isfs = new IsolatedStorageFileStream(fileName,
FileMode.Create, isf))
{
using (StreamWriter sw = new StreamWriter(isfs))
40. Gestión de estado (almacenamiento aislado)
private string LoadData(string fileName)
{
string data = String.Empty;
using (IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication())
{
using (IsolatedStorageFileStream isfs = new
IsolatedStorageFileStream(fileName,
FileMode.Open, isf))
{
using (StreamReader sr = new StreamReader(isfs))
{
string lineOfData = String.Empty;
while ((lineOfData = sr.ReadLine()) != null)
data += lineOfData;
}
}
}
return data;
}
41. Gestión de estado: Almacenamiento Aislado
Solicitud de incremento de cuota
Debe de usarse IsolatedStorageFile.TryIncreaseQuotaTo()
void OnMouseLeftButtonDown(…) {
using (IsolatedStorageFile store =
IsolatedStorageFile.GetUserStoreForApplication()) {
if (store.TryIncreaseQuotaTo(2 * 1024 * 1024)) {
// El usuario acepta.
}
else {
// El usuario rechaza -> hay que manejarlo.
}
}
}
43. x:Name
Se debe dar nombre a los elementos XAML que se
quieran usar en el código
Para el acceso a estilos se utiliza el identificador x:Key
Visual Studio declara automáticamente campos para
todos los elementos con atributos x:Name
XAML: <TextBlock x:Name=“Mensaje”/>
public void Page_Loaded(sender, MouseEventArgs e)
{
Mensaje.Text = “¡Hola Mundo!”;
}
44. Evento Page_Loaded
Primera oportunidad para ejecutar código tras la
descarga del plug-in de Silverlight y la carga en el
navegador
Se dispara después de que todos los elementos XAML
han sido descargados y se ha creado el árbol de
elementos
Si busca ejecutar código inmediatamente, considere cargar
el contenido programáticamente en segundo plano
45. Eventos de UIElement (Base)
MouseMove KeyUp
MouseEnter KeyDown
MouseLeave GotFocus
MouseLeftButtonDown LostFocus
MouseLeftButtonUp Loaded
Todas las formas y controles heredan de UIElement, lo
que significa que todos los elementos tienen al menos 10
eventos.
46. Conectándose a los Eventos
Los manejadores de eventos pueden especificarse en
forma declarativa en el XAML:
<Rectangle x:Name=“MyRect” MouseEnter=“MyRect_MouseEnter">
</Rectangle>
public void MyRect_MouseEnter(object sender, MouseEventArgs e)
{
// TODO: añadir código
}
O explícitamente en el archivo de code-behind
Programáticamente por medio del manejador de evento
Page_Loaded
47. Eventos (Trucos)
Capturar el evento Mouse Wheel
Silverlight no lo soporta , pero podemos capturar el evento mediante el objeto
HtmlPage.
Veamos cómo funciona par a IE, Opera, Mozilla y Safari.
Declaramos 3 eventos para capturar todas las posibilidades del los navegadores
Por ejemplo, el evento DOMMouseScroll lo usa Mozilla.
public Page() {
InitializeComponent();
HtmlPage.Window.AttachEvent("DOMMouseScroll", OnMouseWheel);
HtmlPage.Window.AttachEvent("onmousewheel", OnMouseWheel);
HtmlPage.Document.AttachEvent("onmousewheel", OnMouseWheel);
}
Nuestro evento controla el “delta change” en la rueda del ratón.
La forma de hacerlo en Mozilla y Safari es diferente a IE u Opera.
48. Eventos (Trucos)
Mozilla/Safari: Comprobar la propiedad llamada “detail”
IE/Opera: Comprobar la propiedad llamada “wheeldelta”
Código completo:
private void OnMouseWheel (object sender, HtmlEventArgs args) {
double mouseDelta = 0;
ScriptObject e = args.EventObject;
// Mozilla and Safari
if (e.GetProperty("detail") != null) {
mouseDelta = ((double)e.GetProperty("detail"));
}
// IE and Opera
else if (e.GetProperty("wheelDelta") != null)
mouseDelta = ((double)e.GetProperty("wheelDelta"));
mouseDelta = Math.Sign(mouseDelta);
}
50. Manejo de hebras de ejecución y la primitiva
BackgroundWorker
Características
Una aplicación Silverlight actualiza la interfaz de usuario desde
la hebra principal de ejecución (Dispatcher)
Puede provocar situaciones intolerables cuando se están procesando
grupos de ficheros locales
P.E.: creando bitmaps a partir de ficheros gráficos del equipo del
usuario que van a ser presentados en pantalla
En estos casos, debiéramos dejar la responsabilidad de la creación del
Bitmap a un método que sea llamado cada vez que se produzca el
evento CompositionTarget.Rendering:
CompositionTarget.Rendering += new EventHandler(CrearBitmap)
51. Manejo de hebras de ejecución y la primitiva
BackgroundWorker
Hebras de ejecución
Así, cada vez que un nuevo elemento (Bitmap, u otro), este construido y
listo para ser mostrado, el motor de interpretación visual (rendering)
actualizará la IU evitando esos lapsus por falta de respuesta
Para actualizar la IU se debiera usar la hebra de IU principal.
Por ejemplo, el siguiente código no funciona:
...
Timer t = new Timer( GetData, null, TimeSpan.Zero, new TimeSpan( 0, 1, 0 ) );
...
public void GetData( object stateInfo ) {
SampleWebServiceSoapClient client = new SampleWebServiceSoapClient();
client.HelloWorldCompleted += new EventHandler<HelloWorldCompletedEventArgs>(
client_HelloWorldCompleted );
client.HelloWorldAsync();
}
private void client_HelloWorldCompleted( object sender, HelloWorldCompletedEventArgs e ) {
// actualizar la IU
}
52. Manejo de hebras de ejecución y la primitiva
BackgroundWorker
Hebras de ejecución
El código anterior devolverá un error “Invalid cross-thread access“
La razón es que se intenta acceder a la IU principal desde otra hebra, lo
que podría tener problemas de seguridad
La solución es utilizar un objeto DispatcherTimer, en lugar de
System.Threading.Timer que utiliza el ejemplo
El problema es que la hebra principal (Dispatcher) no puede ser invocada
desde un System.Threading.Timer
DispatcherTimer está precisamente pensado para eso
También es conveniente en ocasiones el uso del evento
CompositionTarget.Rendering: veremos un ejemplo claro en el apartado de
Cajas de Diálogo del sistema (FileOpen dialog)
El código resultante de utilizar esta segunda aproximación sería el
siguiente:
53. Manejo de hebras de ejecución y la primitiva
BackgroundWorker
DispatcherTimer
DispatcherTimer t = new DispatcherTimer();
t.Interval = new TimeSpan( 0, 0, 1 );
t.Tick += new EventHandler( RefreshData );
t.Start();
...
private void RefreshData( object sender, EventArgs e) {
SampleWebServiceSoapClient client = new SampleWebServiceSoapClient();
client.HelloWorldCompleted += new EventHandler
<HelloWorldCompletedEventArgs>(client_HelloWorldCompleted);
client.HelloWorldAsync();
}
private void client_HelloWorldCompleted( object sender,
HelloWorldCompletedEventArgs e ) {
lastUpdated.Text = DateTime.Now.ToLongTimeString();
}
56. Recursos (externos e internos al control)
Resource (continuación)
Problemas posibles: Uri’s no accesibles al ser generadas
por código, etc.
Solución: Uri’s relativas al ensamblado:
<Image Source=”/{assemblyShortName};component/Foto.jpg”/>
Podemos extraer un recurso programáticamente
mediante:
Application.GetResourceStream(uri).Stream
Content
Se añade al .XAP (no a la DLL), en el directorio raíz conceptual de la
aplicación
Accesible utilizando Uri’s relativas a la raíz de la aplicación, y por tanto,
incluyendo la barra inicial:
<Image Source=”/Foto.jpg” />
Es lo que tiene más sentido cuando un recurso es utilizado por más de un
ensamblado de la aplicación
57. Recursos (externos e internos al control)
None
No se copia en el XAP, pero el valor de metadato
CopyToOutputDirectory , garantizará que es copiado junto
al XAP en el destino de la instalación.
Accesibles mediante Uri’s relativas respecto a la raíz de la
aplicación (con barra inicial, por tanto)
<Image Source=”/Foo.jpg” />
Preferible si el recurso ocupa mucho espacio
Si se trata de vídeo, podemos utilizar la técnica del “streaming adaptativo”,
que es un complemento que se instala sobre el servidor IIS y permite realizar
una descarga inteligente del recurso de vídeo, en función del ancho de banda
y otros factores.
No marcados (externos al proyecto)
Se recuperan mediante URI’s absolutas
59. Streaming Adaptativo
Streaming Adaptativo
Extensión de IIS Media Services
Permite streaming hacia clientes Silverlight sobre HTTP
Detecta las condiciones del escenario de transferencia
Requiere la instalación de la extensión sobre IIS 7.0
“Trocea” el contenido multimedia en función de los parámetros
evaluados
Expression Encoder 2 Service Pack 1, permite definir distintos
niveles de calidad personalizados para el contenido multimedia
60. Streaming Adaptativo
Streaming Adaptativo (S.A.)
Más información en http://www.iis.net/extensions/SmoothStreaming
Se puede ver una demo de esta característica en
http://www.iis.net/media/experiencesmoothstreaming
La explicación detallada del funcionamiento del SDK está disponible en
http://msdn.microsoft.com/es-es/library/bb851621(en-us).aspx
En el sitio https://silverlight.live.com/ pueden alojarse gratuitamente hasta
10 Gb de contenido multimedia que ya se configura para su uso mediante
S.A.
62. Recomendaciones para el diseño
Sencillo no significa elegante (o estético), pero casi…
Uniformidad en la selección del tema principal del sitio/aplicación
Pensar siempre si una metáfora visual puede explicar más fácilmente un
proceso que una interfaz de usuario clásica
Si no, usar la versión clásica (actualizada, siempre mejora)
Si la respuesta es positiva, adelante desde 0
Reutilizar lo existente es un viejo principio de la OOP
También es aplicable aquí
No caer en la excesiva demostración de las capacidades de la herramienta
aunque no venga a cuento
Aprender a trabajar con diseñadores (comprender sus motivaciones y
carencias… como ellos comprenden las nuestras)
Además de Blend, el resto de productos de la Suite Expression ofrece
grandes posibilidades
67. Estilos, plantillas y recursos de diseño
En Blend, disponemos del concepto de “Sesión de dibujo”,
vinculada a los elementos Geometry principalmente
Cualquier elemento visual (predeterminado o creado por
nosotros), puede ser modelado mediante el uso de estilos
Blend genera el código XAML automáticamente por
nosotros
Podemos ejecutar el proyecto desde Blend, para lo cual se
crea una página de pruebas automáticamente (F5).
Muchos elementos pueden convertirse en recursos generales
de toda la aplicación o en controles
Brushes a partir de imágenes o vídeos
70. Visual State Manager.
Gestiona estados y grupos de estado
Maneja adecuadamente el modelo “Parts-and-
States”
Permite crear estados visuales que se correspondan
con distintos estados de la lógica de negocio
Se accede a el programáticamente mediante el
objeto VisualStateManager
Podemos pasar de un estado a otro mediante una
simple llamada por código al método
GoToState(“estado”)
73. Vinculación de datos
(Lógica de negocio)
Permite acceder a los componentes compilados
(DLL’s) que representan los objetos de lógica de
negocio
Permite vincularnos directamente con ellos
Capacita para una rápida creación de la interfaz de
usuario de los elementos que esos objetos
representan
Page navigation + logical navigation NavigationManager usa un div y un frame oculto para modificar la history-> obtiene del frame oculto el estado y lo carga Otra posibilidad por probar: usar ajax history control (también usa un truco parecido), usar invocar javascript desde silverlight: http://blogs.solidq.com/ES/CuevaNet/Lists/Posts/Post.aspx?ID=20 Navegacion: Posibilidad: Page.xaml:contenedor con fondo y grid Page.xaml.cs: decide transiciones y carga/descarga de controles Controles-> reciben y gestionan eventos, y deciden transición carga/descarga Animación de appear/disappear lo decide el control (el diseñador) Página = user control Presenter = añadir y quitar controles al grid, y podría añadir una transición común entre páginas Navegación lógica: historial-> controlar history En ajax history: frame con historial, y capturan el IFrameLoad de la pagina con el frame nuevo public static class NavigationHelper { private static Grid root; static NavigationHelper() { root = Application.Current.RootVisual as Grid; } public static void Navigate(TransitionBase transition, UserControl newPage) { UserControl oldPage = root.Children[0] as UserControl; root.Children.Insert(0, newPage); transition.TransitionCompleted += transition_TransitionCompleted; transition.PerformTranstition(newPage, oldPage); } public static void Navigate(UserControl newPage) { UserControl oldPage = root.Children[0] as UserControl; root.Children.Add(newPage); root.Children.Remove(oldPage); } private static void transition_TransitionCompleted(object sender, TransitionCompletedEventArgs e) { root.Children.Remove(e.OldPage); } }
Page navigation + logical navigation NavigationManager usa un div y un frame oculto para modificar la history-> obtiene del frame oculto el estado y lo carga Otra posibilidad por probar: usar ajax history control (también usa un truco parecido), usar invocar javascript desde silverlight: http://blogs.solidq.com/ES/CuevaNet/Lists/Posts/Post.aspx?ID=20 Navegacion: Posibilidad: Page.xaml:contenedor con fondo y grid Page.xaml.cs: decide transiciones y carga/descarga de controles Controles-> reciben y gestionan eventos, y deciden transición carga/descarga Animación de appear/disappear lo decide el control (el diseñador) Página = user control Presenter = añadir y quitar controles al grid, y podría añadir una transición común entre páginas Navegación lógica: historial-> controlar history En ajax history: frame con historial, y capturan el IFrameLoad de la pagina con el frame nuevo public static class NavigationHelper { private static Grid root; static NavigationHelper() { root = Application.Current.RootVisual as Grid; } public static void Navigate(TransitionBase transition, UserControl newPage) { UserControl oldPage = root.Children[0] as UserControl; root.Children.Insert(0, newPage); transition.TransitionCompleted += transition_TransitionCompleted; transition.PerformTranstition(newPage, oldPage); } public static void Navigate(UserControl newPage) { UserControl oldPage = root.Children[0] as UserControl; root.Children.Add(newPage); root.Children.Remove(oldPage); } private static void transition_TransitionCompleted(object sender, TransitionCompletedEventArgs e) { root.Children.Remove(e.OldPage); } }
Page navigation + logical navigation NavigationManager usa un div y un frame oculto para modificar la history-> obtiene del frame oculto el estado y lo carga Otra posibilidad por probar: usar ajax history control (también usa un truco parecido), usar invocar javascript desde silverlight: http://blogs.solidq.com/ES/CuevaNet/Lists/Posts/Post.aspx?ID=20 Navegacion: Posibilidad: Page.xaml:contenedor con fondo y grid Page.xaml.cs: decide transiciones y carga/descarga de controles Controles-> reciben y gestionan eventos, y deciden transición carga/descarga Animación de appear/disappear lo decide el control (el diseñador) Página = user control Presenter = añadir y quitar controles al grid, y podría añadir una transición común entre páginas Navegación lógica: historial-> controlar history En ajax history: frame con historial, y capturan el IFrameLoad de la pagina con el frame nuevo public static class NavigationHelper { private static Grid root; static NavigationHelper() { root = Application.Current.RootVisual as Grid; } public static void Navigate(TransitionBase transition, UserControl newPage) { UserControl oldPage = root.Children[0] as UserControl; root.Children.Insert(0, newPage); transition.TransitionCompleted += transition_TransitionCompleted; transition.PerformTranstition(newPage, oldPage); } public static void Navigate(UserControl newPage) { UserControl oldPage = root.Children[0] as UserControl; root.Children.Add(newPage); root.Children.Remove(oldPage); } private static void transition_TransitionCompleted(object sender, TransitionCompletedEventArgs e) { root.Children.Remove(e.OldPage); } }
Quick sample code in the app.xaml.cs to deal with the startup.