En este quinto artículo sobre MVVM, después de haber montado el Modelo en los anteriores post, y unas pruebas unitarias asociadas al Modelo, vamos a crear la vista, la cual va a estar formada a partir de 3 componentes, aunque todo podría estar en el mismo componente, es más práctico y funcional que esté separado en distintos controles, ya que así nos permite la reutilización de elementos en otros, y es que una de las ventajas más importantes de WPF, es la potencia del marcado XAML, que nos deja introducir controles que contienen a otros que a su vez pueden contener a otros distintos.
En la solución, tenemos un proyecto de WPF, si no es así lo creamos, y lo establecemos como proyecto principal de la compilación. Por defecto, vendrá un control MainWindow.xaml que será la ventana principal de la aplicación. Agregamos un nuevo control de usuario, y en el marcado de este control, al objeto Grid, le agregamos dos filas, en la primera insertamos un StackPanel con orientación vertical, que contenga un TextBox con un ancho mínimo de 200px y un Button alineado a la derecha. En la segunda fila agregamos un objeto ListBox el cual albergará los resultados de la búsqueda que hagamos, que serán las localizaciones que coincidan con el texto del TextBox. Y nos queda algo así:
<UserControl x:Class="WeatherApp.Components.Search" 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" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="300"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition /> </Grid.RowDefinitions> <StackPanel Grid.Row="0" Orientation="Vertical" Margin="5"> <TextBox MinWidth="200"/> <Button Content="Buscar" HorizontalAlignment="Right"/> </StackPanel> <ListBox Grid.Row="1" Margin="5"></ListBox> </Grid> </UserControl>
A continuación agregamos un control tipo Page, este objeto se puede utilizar para integrarlo en un Frame, el cual trae de serie la gestión de una pila de páginas navegadas, y los controles de navegación para poder ir atrás o hacía adelante. La página estará compuesta por un Grid de dos columnas, la primera que se autoajuste y la segunda que se ajuste el ancho al contenido, en la primera agregamos un objeto Image, que de momento no configuramos su Source, y en la segunda agregamos un StackPanel en el que los objetos se orienten verticalmente, y que su alineación vertical sea también en el centro, este panel contiene a su vez dos TextBlock que albergarán la temperatura y el nombre de la ciudad. Por último agregamos un objeto Border con un ColSpan y orientado arriba a la derecha, con dos RadioButton los cuales permitirán el cambio entre grados Farenheit y Celsius.
<Page x:Class="WeatherApp.Components.Weather" 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" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="300" Title="Weather"> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition/> <ColumnDefinition Width="Auto"/> </Grid.ColumnDefinitions> <Image Grid.Column="0" Stretch="Uniform" VerticalAlignment="Center"/> <StackPanel VerticalAlignment="Center" Orientation="Vertical"> <TextBlock FontSize="36" FontWeight="Bold"/> <TextBlock FontSize="18" FontWeight="Bold"/> </StackPanel> <Border Grid.ColumnSpan="2" CornerRadius="5" VerticalAlignment="Top" HorizontalAlignment="Right" Margin="3"> <StackPanel Orientation="Horizontal"> <RadioButton GroupName="Degree">Fº</RadioButton> <RadioButton GroupName="Degree">Cº</RadioButton> </StackPanel> </Border> </Grid> </Page>
Seguido, introducimos en el MainWindow un objeto Frame, y a continuación un objeto Expander, que se expande hacía a la izquierda, y lo ubicamos alineado a la derecha, en el Header introducimos un TextBlock con el texto «Búsqueda» y rotado 90 grados, y en el Content el componente de búsqueda que hemos creado antes.
<Window x:Class="WeatherApp.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:comp="clr-namespace:WeatherApp.Components" Title="MainWindow" Height="350" Width="525"> <Grid> <Frame /> <Expander ExpandDirection="Left" HorizontalAlignment="Right"> <Expander.Header> <TextBlock Text="Búsqueda" > <TextBlock.LayoutTransform> <TransformGroup> <ScaleTransform/> <SkewTransform/> <RotateTransform Angle="90"/> <TranslateTransform/> </TransformGroup> </TextBlock.LayoutTransform> </TextBlock> </Expander.Header> <comp:Search /> </Expander> </Grid> </Window>
En el siguiente post, continuaremos elaborando el ViewModel de cada uno de estos objetos, y los relacionaremos para después continuar haciendo los Binding a las propiedades.