martes, 27 de noviembre de 2012

Navegar desde una Page que está dentro de un Frame

Haciendo la aplicación WPF, y saltándome la arquitectura MVVM hasta que le coja el tranquillo a cosas aún más básicas como esta, me he encontrado con ciertas dificultades para poder pasar de una página a otra.

Esto es debido a que la aplicación corre en una Windows con un Frame en su interior y dentro de este invoco a las Page oportunas. Así la window tiene una declaración tal que así:

<Window x:Class="TSA_KMSPanel.MainWindow"
       
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
       
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
       
Title="KMSPanel" >
    <
Grid>
        <Frame Name="FrameCuerpo" Source="ListadoClientes.xaml" NavigationUIVisibility="Hidden">
        </
Frame>
    </
Grid>
</
Window>

La página que abre por defecto es Listadoclientes.xaml que tiene un botón que es el que le hace ir a la siguiente página. Y que su xaml es algo así:

<Page x:Class="TSA_KMSPanel.ListadoClientesView"
     
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
     
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
     
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
     
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
     
Title="ListadoClientes">

    <
Grid>
       
<Button x:Name="bRecarga"
               
Content=""
               
Cursor="Hand"
               
Click="bRecarga_Click" />
 
    </Grid>
</
Page>

Como has visto las dos únicas cosas que he añadido es que el cursor sea una dedito cuando se pone por encima, y el evento que se lanza cuando el click. Y ahora vamos al truco del almendruco en el code behind.

private void bRecarga_Click(object sender,RoutedEventArgs e)
{
   
this.NavigationService.Navigate(newUri("PantallaClientes.xaml",UriKind.Relative));
}

Y ¿cómo consigo que no salga la barra espantosa de navegación?, pues fíjate en la declaración del frame que va a contener todas las páginas de la aplicación le he dicho:

NavigationUIVisibility="Hidden"

Y con esto tengo la enorme ventaja de que el NavigationService me permite cosas tan chulas como historial de navegación, etc.

lunes, 26 de noviembre de 2012

Cuando ICommand decide no aparecer

Siguiendo con el proyecto en WPF me he encontrado con un retorcido funcionamiento del Visual que me ha dejado perplejo un buen rato.

El proyecto de WPF está dividido en tres capas diferentes: View, ViewModel y Entidades.

Pues bien, me pongo ha implementar el DelegateCommand y despues de darle a los dos puntos no me reconoce el interface ICommand

public class DelegateCommand : ICommand

Me voy a buscar en MSDN y veo que su espacio de nombres es:

using System.Windows.Input;

Pero nada sigue sin aparecerme ni reconocerlo. Asique me pongo a buscar las diferencias en las referencias de ambos proyectos: uno WPF y el otro de clases, y después de varias pruebas y errores he encontrado cual es la referencia que hay que añadir:

PresentationCore

Y ala, todo a funcionar corréctamente.

Como rellenar un GridView en WPF siguiendo MVVM - II

En el artículo anterior describí a grosso modo todo lo que necesitaba para poder rellenar un GridView en WPF, desde la base de datos, siguiendo el patrón MVVM. Bueno, realmente aún me falta implementar el locator para quitar del todo el código en el codebehind del xaml.cs.

Pero ahora me voy a centrar en la Vista y cómo obtener un GridView (como los de ASP.NET) o “Grilla” (como dicen los compañeros latinoamericanos) con contenido.

Para ello primero utilizo un ListView, dentro del cual defino una vista, y dentro de esta vista un GridView.

<ListView Name="ViewClientes">
     <ListView.View>
                <
GridView>
                    <
GridViewColumn Header="Idcliente" />
                    <
GridViewColumn Header="Nombre" />
                    <
GridViewColumn Header="Apellidos" />
                </
GridView>
       </
ListView.View>
   </
ListView>

Si lanzamos nuestro código obtendremos un GridView vacio, pero con los encabezados. Para recuperar los datos lo primero es decirle al ListView que debe de mostrar, teniendo en cuenta que ya enlazamos en el artículo anterior el Datacontext de la Vista.

<ListView Name="ViewClientes"Margin="50,50,50,0"ItemsSource="{Binding ListadoClientes}">

Fíjate que le estoy diciendo que utilice la propiedad pública ListadoClientes de la clase del ViewModel PantallaClientes. Y como esta propiedad es un List<Cliente> pues ya puedo definir en las columnas del GridView que campo quiero que muestre.

<ListView Name="ViewClientes" ItemsSource="{Binding ListadoClientes}">
<
ListView.View>
  <
GridView>
    <
GridViewColumn Header="Idcliente" DisplayMemberBinding="{Binding IdCliente}" />
    <
GridViewColumn Header="Nombre" DisplayMemberBinding="{Binding Nombre}" />
    <
GridViewColumn Header="Apellidos" DisplayMemberBinding="{Binding Apellidos}" />
  </
GridView>
</
ListView.View>
</
ListView>

 
 

Y con esto ya está funcionando!!

Como rellenar un GridView en WPF siguiendo MVVM

Estoy aprendiendo WPF siguiendo el libro de Introducción a programación en Windows 8 y Windows Phone 8 de Josué Yeray, Rafael Serna  e Ibón Landa.

Así, cuando me he enfrentado con representar una lista de datos en pantalla, he encontrado rápidamente la utilidad de la Vista GridView de las List View.

Así, tengo una entidad de Cliente, que entre otros campos tiene un IdCliente, un Nombre y un Apellidos.

    public partial class Cliente
  
{
      
public int IdCliente {get;set; }
      
public string Nombre {get;set; }
      
public string Apellidos {get;set; }
    }

En la capa de Datos he creado una capa que realiza la recuperación de la colección de clientes que está persistida en la base de datos, a través del EF.

 public class ClientesDAL
   
{

       
/// <summary>
        ///
Devuelve el listado total de clientes
       
/// </summary>
        /// <returns></returns>
       
public List<Cliente> GetClientesList()
        {
           
KMSPanelModelContainer contexto = new KMSPanelModelContainer();
           
return (from Cliente cliente in contexto.Clientes
                   
select cliente).ToList();
        }

       
public Cliente GetClienteById(Cliente pCliente)
        {
           
KMSPanelModelContainer contexto = new KMSPanelModelContainer();
           
return (from Cliente cliente in contexto.Clientes
                  
where cliente.IdCliente == pCliente.IdCliente
                  
select cliente).FirstOrDefault();
        }
    }

En el ViewModel, tengo mi clase que va a ser el DataContext y en donde cargo un listado de clientes en la propiedad pública.

    public class PantallaClientes : VMBase
   
{
       
private List<Cliente> listadoClientes;
       
public List<Cliente> ListadoClientes
        {
           
get { return GetClientesList(); }
           
set { listadoClientes = value; }
        }

       
public PantallaClientes()
        {
            listadoClientes = GetClientesList();
        }

       
/// <summary>
        ///
Devuelve el listado de clientes
       
/// </summary>
        /// <returns></returns>
       
private List<Cliente> GetClientesList()
        {
           
ClientesDAL clientesDAL = new ClientesDAL();
           
return clientesDAL.GetClientesList();
        }
    }

Ahora (perdonarme el código en el codebehind, pero aún no lo he terminado del todo) enlazo el DataContext de la Vista (View).

    public partial class MainWindow : Window
   
{
       
public MainWindow()
        {
            InitializeComponent();
           
this.DataContext = new TSA_KMSPanel.ViewModel.PantallaClientes();
        }
    }

Y ahora llegamos al binding en el XAML, pero el cual lo voy a poner en el siguiente post.

Donde debe estar la cadena de conexión de las Entidades (EF)

Con este post voy a iniciar una serie de artículos sobre una aplicación WPF que estoy realizando y que me está entusiasmando.

El primer problema, y que he vivido en otras ocasiones es que siempre utilizo una arquitectura de capas y esta vez no iba a ser diferente. Así el proyecto sigue la arquitectura del patrón MVVM, y está compuesto por cuatro proyectos:

  • La Vista
  • El ViewModel
  • Las Entidades (Entity Framework)
  • Los Test

El problema venía que cuando lanzaba el proyecto para recuperar un listado de la base de datos a través del proyecto de Entidades que se encarga del accedo a datos, el proyecto ViewModel me decía que no encontraba la cadena de conexión.

La solución es simple cuando ya la conoces: crea un nuevo fichero App.config en el proyecto de la Vista e introduce en el la cadena de conexión. Así la tendrás disponible para todos los proyectos ya que el punto de entrada, y donde va a buscar esa configuración.

Espero que sea de utilidad.

viernes, 23 de noviembre de 2012

Community Day 2012, el sabor agridulce de un gran evento

Primero quiero dar las gracias a MS, y a Bonin (especialmente) por invitarme por segunda vez a este evento de los MVP de España; es todo un honor y un privilegio el poder estar rodeado de, posiblemente, el grupo más selecto de profesionales en tecnologías de Microsoft.

El año pasado el evento estuvo muy centrado en sesiones técnicas, y parece que hubo suficientes comentarios como para que la organización de la convocatoria de 2012 empujara el péndulo al otro lado.
Así nos encontramos con un evento en grupos de 5 personas que nos llevó a caminar por el centro de Madrid en la búsqueda de fotos y datos singulares de la capital, y que fue muy divertido  a pesar del obvio bajo estado físico de quien escribe estas líneas.

Acabada la Ginkana, repartieron los premios entre aplausos, bromas, chanzas y una lluvia de comida. Me monté en mi caballo de hierro y me fui, cansado y con dolor de espalda, a mi casa con una sensación agridulce.

Si bien el día anterior en el TechDay, desde mi punto de vista, el evento fue todo un éxito y me lo pasé en grande hablando con mucha gente muy interesante y disfruté de charlas técnicas aprendiendo de todas ellas; en cambio en el Community Day el formato de competición en grupos solitarios, me toco un grupo buenísimo, impidió seguir haciendo networking y, además, no hubo la reunión que tanto llevo pidiendo para organizarnos un poquito los Technical Rangers.

Es más, no hubo ninguna reunión, ni charla, ni nada más que 3 horas de caminar por Madrid.

Somos profesionales, somos conocidos, pero muy pocos somos tan amigos como para pedir días de vacaciones, o dedicar un Viernes en hacer una actividad de este estilo. Es más, y espero no levantar ningún revuelo, hay algo raro en el ambiente de los MVP, unas relaciones amor-odio-competencia  ocultas tras sonrisas y buenas palabras, que me ha dejado más bien perplejo y con la sensación de ser un tanto pardillo al creer que “to er mundo es bueno”.

El día anterior, ponentes en el TechDay me comentaban que no se pueden hacer charlas técnicas potentes y profundas  porque el gran público no las puede seguir. Por ello esperé  para el día siguiente alguna charla avanzada para un público mucho más profesional y con conocimiento. Un ponente potente, tal vez, o mesas redondas en donde los mejores profesionales le puedan decir de viva voz a MS qué necesitan para mejorar o para hacer mejor su  labor de difusión.

En resumen, utilizar el tiempo en hacer algo útil. Algo que supere el subir fotos a Twiter y que nos deje un buen sabor de boca, como profesionales, de que hemos estado en un evento especial, orgullosos de haber sido merecedores de ser invitados.

Desde el punto de vista de Technical Ranger, ha sido un fiasco. El año pasado en Fuengirola sacamos en claro, en la reunión que hicimos, que había sido un éxito el programa. Y que teníamos que organizarnos un poco para conseguir aún mejores resultados. Pero este año no solamente el programa languidece, si no que se ha perdido la oportunidad de tenernos a todos juntos para poder encontrar donde estamos y a dónde queremos ir.

Y creo, pero es solo mi opinión, que el problema es que no ha habido objetivo claro de para qué nos reunimos en este Community. Da la sensación, pero es solo una sensación y por ello posiblemente injusta, de que se ha volcado la organización tanto en el TechDay, que ha llegado desfondada al Community y lo ha despachado contratando una empresa de eventos empresariales.

De todas formas, y a pesar de este sabor agridulce, me quedo con las conversaciones con tantos MVP, MSP, gente de MS y todos los profesionales a los que tanto respeto y a los que, en cada evento, les voy cogiendo un aprecio personal. Y estoy impaciente por que llegue el Community del 2013 y volver a merecerme ser invitado.

Muchas gracias.