Faire une application météo WPF Windows Presentation Framework

 

WPF pour créer des applications Windows Desktop

WPF en gros pour faire court c’est une application desktop avec des fenêtres. WPF est le successeur de Winform, personnellement je ne connais pas du tout Winform, disons que c’est la génération avant WPF. On va faire avec WPF, c’est une façon de programmer MVVM (Model-View-ViewModel). En gros ça veut dire qu’il y a une liaison entre le visuel et le modèle de données (les données elles-même appelé ViewModel), si vous modifiez une valeur sur l’interface graphique, cela va se répercuter dans la variable. Cette dernière variable peut être modifiée programmatiquement.

La programmation MVVM existe aussi sur le web, j’en ai pas mal fait avec AngularJS. L’avantage est une simplification de la mise à jour des données entre l’interface et la base de données.

Création d’une application WPF dans VisualStudio

Pour tout projet C#, vous êtes obligé de passer par VisualStudio, je ne pense pas qu’il y ait d’autres alternatives, c’est tant mieux ainsi, on va se concentrer mieux.

Concevoir une fenêtre en WPF

La différence avec une application est la présence d’une interface graphique, qui dit interface graphique de nos jour dit langage xml, dans le cas de WP, Microsoft a pondu une version de xml qui s’appelle le XAML.

A partir de là vous avez le choix de concevoir votre interface de manière graphique avec la souris, ou d’écrire directement en XAML, pour avoir un controle plus fin, mais les deux sont équivalent. Vous devez jongler entre les deux pour voir de quoi il retourne. A terme le design graphique vous permettra d’aller plus vite, mais la programmation en XAML va vous permettre de caler les éléments au pixel près.

xaml

Avec VisualStudio, les deux fenêtres graphique et textuelle se mettent à jour automatiquement dès qu’on modifie un élément d’une des deux fenêtres. Donc si vous êtes débutant, c’est un bon moyen d’apprendre.

Comment faire vivre l’interface graphique?

C’est bien beau de faire une belle interface graphique, quoique vous aurez des surprises car avec le glisser déplacer ce n’est pas si évident, en plus il y a énormément de composants, mais comment allons nous attacher du code à un bouton par exemple?

Il y a deux fichiers, MainWindow.xaml et MainWindow.xaml.cs, celui qui a l’extension cs correspond au code C#, donc vous y écrirez toutes les fonctions, on appelle le code derrière un bouton un code-behind tout simplement. Regardez comment le XAML et le code C# sont liés.

A chaque élément est attaché une fonction, par exemple, pour un bouton :

<Button x:Name="button1" Content="Meteo Toulouse" HorizontalAlignment="Center" Margin="10,10,10,0" VerticalAlignment="Top" Width="75" Click="GetMeteoToulouse_Click" />

On a un attribut Click dont la valeur est égale à GetMeteoToulouse_Click. et dans le code-behind, dans le fichier MainWindow.xaml.cs est automatiquement inséré un code du type :

  private void GetMeteoToulouse_Click(object sender, RoutedEventArgs e)
 { 
   //.......
   // code c# ici
 }

Cette fonction prend en argument deux paramètres. En WPF, il y a la notion très importante d’événement (RoutedEvent, mais en fait c’est un event), un click sur un bouton est un événement, une mise à jour d’une valeur est un événement, il faut donc bien comprendre comment les événements sont gérés.

Si le bouton est cliqué, c’est la méthode ci-dessus qui va s’exécuter.

Pour faire simple voici le code du XAML:

<Window x:Class="WpfApplication3.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApplication3"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <WrapPanel x:Name="wrapPanel1" Height="100" Width="100"/>
        <Label x:Name="label" 
               HorizontalAlignment="Stretch" 
               Margin="10,202,37,10" 
               FontSize="20"
               Padding="5"
               Loaded="label_Loaded" 
               VerticalAlignment="Center" RenderTransformOrigin="0.5,0.5" Height="107">
        </Label>

        <ScrollViewer HorizontalAlignment="Left" Height="195" Margin="10,80,0,0" VerticalAlignment="Top" Width="497">
            <StackPanel Grid.Row="0" Height="110" Orientation="Horizontal" RenderTransformOrigin="0.5,0.5">
                <StackPanel.RenderTransform>
                    <TransformGroup>
                        <ScaleTransform/>
                        <SkewTransform/>
                        <RotateTransform/>
                        <TranslateTransform Y="-30"/>
                    </TransformGroup>
                </StackPanel.RenderTransform>
                <Button x:Name="button" ToolTip="Un café?" Content="Shrink Label Text" HorizontalAlignment="Center" Margin="10,10,0,60" VerticalAlignment="Top" Width="100" Click="button_Click_1"/>
                <Button x:Name="button1" Content="Meteo Toulouse" HorizontalAlignment="Center" Margin="10,10,10,0" VerticalAlignment="Top" Width="75" Click="GetMeteoToulouse_Click" />
            </StackPanel>
        </ScrollViewer>

    </Grid>
</Window>

et le code behind :

using System;
using System.Windows;
using System.Windows.Controls;
using System.IO;
using System.Windows.Media.Imaging;

namespace WpfApplication3
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {

        public MainWindow()
        {
            InitializeComponent();
        }

        private void label_Loaded(object sender, RoutedEventArgs e)
        {
            var label = sender as Label;

        }


        /// <summary>
        /// demande le temps qu'il fait pour Toulouse
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void GetMeteoToulouse_Click(object sender, RoutedEventArgs e)
        {
            //get weather !
            var url = "http://api.openweathermap.org/data/2.5/weather?q=Toulouse&APPID=ici-la-cle-api";
            var webrequest = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(url);

            using (var response = webrequest.GetResponse())
            using (var reader = new StreamReader(response.GetResponseStream()))
            {
                var result = reader.ReadToEnd();

                var jObject = Newtonsoft.Json.Linq.JObject.Parse(result);
                this.label.Content = ((string)jObject["weather"][0]["main"]);
                //Console.WriteLine((string)jObject["weather"][0]["icon"]);
                //Console.WriteLine(Convert.ToString(Math.Round((float)jObject["main"]["temp"] - 273.15)));

                //on va chercher l'image sur le serveur de l'api
                var image = new Image();
                var fullFilePath = @"http://openweathermap.org/img/w/"+ (string)jObject["weather"][0]["icon"] + ".png";

                BitmapImage bitmap = new BitmapImage();
                bitmap.BeginInit();
                bitmap.UriSource = new Uri(fullFilePath, UriKind.Absolute);
                bitmap.EndInit();

                image.Source = bitmap;
                wrapPanel1.Children.Add(image);

            }
        }

    }
}

Cette application est un peu codé à la rache, mais est fonctionnelle, il y a juste la clé API de OpenWeather qu’il faut créer pour avoir accès aux informations.

Retour en haut