LightSwitch nos da la capacidad de importar datos de numerosas fuentes. Estos datos se pueden mostrar al usuario final en una rejilla editable (grid) por la simple creación de pantallas de tipo rejilla editable.
Los nombres de las columnas de la rejilla se corresponden con los nombres de los campos de la tabla que importamos. Esto funciona para la mayoría de los casos, pero en ciertas situaciones se necesita que estos nombres sean dinámicos. Por ejemplo, considera una aplicación para el Top 5 de coches del año con la base de datos diseñada de la siguiente manera:
CarRating
AttributeName
|
Car1
|
Car2
|
Car3
|
Car4
|
Car5
|
Frenado
|
Bueno
|
Muy bueno
|
Bueno
|
Bueno
|
Bueno
|
Aceleración
|
Excelente
|
Malo
|
Muy bueno
|
Muy bueno
|
Bueno
|
Velocidad
|
Excelente
|
Excelente
|
Muy bueno
|
Bueno
|
Malo
|
Manipulación
|
Muy bueno
|
Excelente
|
Malo
|
Malo
|
Bueno
|
Car
Name
|
Ranking
|
BMW
|
5
|
Mercedes
|
4
|
Porsche
|
3
|
Aston Martin
|
2
|
Ferrari
|
1
|
Ahora queremos mostrar la tabla de clasificación de coches pero en lugar de "Car1", Car2 ", etc..., en nuestros nombres de las columnas queremos leer de la tabla "Car", obtener los 5 mejores coches y sustituir los nombres de las columnas con los nombres que se obtienen de la tabla.
Con el fin de hacer eso, empezaremos con la creación de las 2 tablas anteriores: CarRating y Car. CarRating tendrá campos de tipo cadena llamados AttributeName, Car1, Car2, Car3, Car4 y Car5. La tabla Car tendrá un campo de tipo cadena llamado Name y un campo tipo entero denominado Ranking.
Aquí está la imagen de las tablas tal como se ve en LightSwitch:
A continuación, creamos una pantalla de tipo rejilla para CarRating. Así que haz clic con el boton derecho en el nodo de pantallas desde el Explorador de Soluciones y despues haz clic en Agregar pantalla. Selecciona la plantilla de rejilla editable y selecciona CarRatings como origen de datos y el nombre CarRatingsGridScreen.
Ahora desde el Explorador de Soluciones, haz clic en el CarRatingsGridScreen y selecciona Ver código de pantalla.
Esto te llevará al editor de código. Reemplaza todo el código con lo siguiente (asegúrate de que el nombre de espacio de nombres es coherente con el resto de los archivos de código de usuario):
VB
Imports System.Collections.Generic
Imports System.Linq
Imports Microsoft.LightSwitch
Imports Microsoft.LightSwitch.Presentation
Imports Microsoft.LightSwitch.Presentation.Extensions
Imports System.Windows.Controls
Imports Microsoft.LightSwitch.Threading
Namespace LightSwitchApplication
Partial Public Class CarRatingsGridScreen
Private Sub CarRatingsGridScreen_Created()
AddHandler Me.FindControl("grid").ControlAvailable, AddressOf CarRatingsGrid_ControlAvailable
End Sub
Private Sub CarRatingsGrid_ControlAvailable(sender As Object, e As ControlAvailableEventArgs)
UpdateColumnNames(DirectCast(e.Control, DataGrid))
End Sub
Private Sub UpdateColumnNames(carRatingsGrid As DataGrid)
Me.Details.Dispatcher.BeginInvoke(
Sub()
Dim top5Cars = Me.DataWorkspace.ApplicationData.Cars.OrderBy(Function(car) car.Ranking).Take(5).Execute()
Dim carNames As String() = top5Cars.[Select](Function(car) car.Name).ToArray()
Dispatchers.Main.BeginInvoke(
Sub()
Dim rowTemplate As IContentItem = DirectCast(carRatingsGrid.DataContext, IContentItem).ChildItems(0)
For index As Integer = 0 To carNames.Length - 1
'start with the second column of the grid
rowTemplate.ChildItems(index + 1).DisplayName = carNames(index)
Next
End Sub)
End Sub)
End Sub
End Class
End Namespace
C#
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.LightSwitch;
using Microsoft.LightSwitch.Presentation;
using Microsoft.LightSwitch.Presentation.Extensions;
using System.Windows.Controls;
using Microsoft.LightSwitch.Threading;
namespace LightSwitchApplication
{
public partial class CarRatingsGridScreen
{
partial void CarRatingsGridScreen_Created()
{
this.FindControl("grid").ControlAvailable += CarRatingsGrid_ControlAvailable;
}
void CarRatingsGrid_ControlAvailable(object sender, ControlAvailableEventArgs e)
{
UpdateColumnNames((DataGrid)e.Control);
}
private void UpdateColumnNames(DataGrid carRatingsGrid)
{
this.Details.Dispatcher.BeginInvoke(() =>
{
var top5Cars = this.DataWorkspace.ApplicationData.Cars.OrderBy(car => car.Ranking).Take(5).Execute();
string[] carNames = top5Cars.Select(car => car.Name).ToArray();
Dispatchers.Main.BeginInvoke(() =>
{
IContentItem rowTemplate = ((IContentItem)carRatingsGrid.DataContext).ChildItems[0];
for (int index = 0; index < carNames.Length; index++)
{
//start with the second column of the grid
rowTemplate.ChildItems[index + 1].DisplayName = carNames[index];
}
});
});
}
}
}
En el código anterior, lo primero que estamos haciendo es el registro de controlador de eventos con el evento CarRatingsGrid_ControlAvailable de nuestro DataGrid. Esto está ocurriendo en el método CarRatingsGridScreen_Created.
Cuando la rejilla de datos en la pantalla aparece, nuestro método CarRatingsGrid_ControlAvailable se disparará. Este método tiene un argumento de tipo ControlAvailableEventArgs desde la cual podemos obtener el control real de Silverlight.
A continuación pasamos el control al método UpdateColumnNames desde CarRatingsGrid_ControlAvailable. Dado que el método se ejecuta en el subproceso principal, vamos al hilo lógico para obtener los 5 primeros nombres de coches y almacenarlos en una matriz (no podemos acceder a los datos del DataWorkspace en el hilo principal). Entonces volvemos al hilo principal y establecemos los nombres de columnas en la rejilla.
Ahora bien, para comprobar que funciona, tendremos que agregar unos cuantos registros en la tabla "Car". Así que crearemos una pantalla de rejilla editable para la tabla de coches y añadiremos unos pocos registros. Despues abre una nueva instancia de la CarRatingsGridScreen, debe tener los nombres de las columnas actualizadas.
Aquí está una captura de cómo deben ser las las pantallas en tiempo de ejecución:
A pesar de este post es sobre la configuración de los nombres de las columnas de forma dinámica, se puede extender a cualquier tipo de manipulación del interfaz de usuario. Por ejemplo, podemos obtener un identificador para un control de cuadro de texto en una pantalla y establecer su fondo en amarillo sobre la base de un cálculo, o podemos cambiar el color de la fuente de una celda de la rejilla de datos. El mismo concepto se aplica - obtener un identificador para el control de Silverlight subyacente y cambiar cualquier propiedad que deseemos en el proceso del interfaz de usuario.