Rechercher
 

Améliorations / Corrections

Vous avez des améliorations (ou des corrections) à proposer pour ce document : je vous remerçie par avance de m'en faire part, cela m'aide à améliorer le site.

Emplacement :

Description des améliorations :

Utilisation d'éléments 2D dans un canvas WPF

Nous allons voir, avec cet exemple de code WPF, comment produire un affichage d'une courbe (sinus ou cosinus) à l'intérieur d'un canvas WPF et en utilisant des contrôles 2D. Les contrôles 2D WPF sont : Rectangle, Ellipse, Line et Path. Pour autant, dans cet exemple nous n'utiliserons que des contrôles de type Line.

Voici une capture d'écran montrant le résultat produit par cet exemple.

Définition XAML de la fenêtre

Voici la définition XAML de notre fenêtre : on y trouve pricipalement un contrôle Canvas ainsi que deux boutons permettant de charger la courbe en court d'affichage.

 1 
 2 
 3 
 4 
 5 
 6 
 7 
 8 
 9 
 10 
 11 
 12 
 13 
 14 
 15 
 16 
 17 
 18 
 19 
 20 
 21 
 22 
 23 
 24 
 25 
 26 
 27 
 28 
<Window x:Class="DrawCurve.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:DrawCurve"
        mc:Ignorable="d"
        Title="MainWindow" Height="493.057" Width="403.273" SizeChanged="Window_SizeChanged">

    <Grid>
        
        <Grid.RowDefinitions>
            <RowDefinition Height="50"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        
        <StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
            <Button x:Name="BtnSinus" Style="{StaticResource buttonStyle}" 
                    Click="BtnSinus_Click">Sinus</Button>
            <Button x:Name="BtnCosinus" Style="{StaticResource buttonStyle}" 
                    Click="BtnCosinus_Click">Cosinus</Button>
        </StackPanel>
        
        <Canvas Grid.Row="1" x:Name="Canvas" Loaded="Canvas_Loaded" />
        
    </Grid>
    
</Window>
La définition XAML de la fenêtre

Définition du style

Ensuite, on ajoute un peu de style dans le fichier App.xaml afin de décorer nos deux boutons (avant-plan blanc sur fond rouge).

 1 
 2 
 3 
 4 
 5 
 6 
 7 
 8 
 9 
 10 
 11 
 12 
 13 
 14 
 15 
 16 
 17 
<Application x:Class="DrawCurve.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:DrawCurve"
             StartupUri="MainWindow.xaml">
    <Application.Resources>

        <Style x:Key="buttonStyle" TargetType="{x:Type Button}">
            <Setter Property="Margin" Value="10,10,10,10" />
            <Setter Property="Width" Value="100" />
            <Setter Property="Height" Value="30" />
            <Setter Property="Background" Value="Red" />
            <Setter Property="Foreground" Value="White" />
        </Style>

    </Application.Resources>
</Application>
Définition du style à appliquer aux boutons de notre calculatrice

Le code permettant de mettre à jour les éléments 2D de la courbe

A chaque appui sur un bouton, il faudra supprimer tous les éléments 2D présents dans le contrôle Canvas. Ensuite, il faut regénére tous les segments nécessaires pour afficher la courbe sélectionnées. Ces segments seront positionnés au pixel prêt (étant donné le layout utilisé : Canvas).

 1 
 2 
 3 
 4 
 5 
 6 
 7 
 8 
 9 
 10 
 11 
 12 
 13 
 14 
 15 
 16 
 17 
 18 
 19 
 20 
 21 
 22 
 23 
 24 
 25 
 26 
 27 
 28 
 29 
 30 
 31 
 32 
 33 
 34 
 35 
 36 
 37 
 38 
 39 
 40 
 41 
 42 
 43 
 44 
 45 
 46 
 47 
 48 
 49 
 50 
 51 
 52 
 53 
 54 
 55 
 56 
 57 
 58 
 59 
 60 
 61 
 62 
 63 
 64 
 65 
 66 
 67 
 68 
 69 
 70 
 71 
 72 
 73 
 74 
 75 
 76 
 77 
 78 
 79 
 80 
 81 
 82 
 83 
 84 
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Shapes;

namespace DrawCurve
{

    public partial class MainWindow : Window
    {
        private delegate double Function(double value);
        private Function function = Math.Sin;

        public MainWindow()
        {
            InitializeComponent();
        }


        private void Redraw()
        {
            double xTrans(double px) => Canvas.ActualWidth * (px + Math.PI) / (2 * Math.PI);
            double yTrans(double py) => Canvas.ActualHeight * (1 - (py + 1) / 2);

            Canvas.Children.Clear();

            DrawLine(0, Canvas.ActualHeight / 2, Canvas.ActualWidth, Canvas.ActualHeight / 2, Color.FromRgb(255, 0, 255), 2);
            DrawLine(Canvas.ActualWidth / 2, 0, Canvas.ActualWidth / 2, Canvas.ActualHeight, Color.FromRgb(255, 0, 255), 2);

            Color color = Color.FromRgb(255, 0, 0);
            double step = 0.1;
            double oldX = -Math.PI;
            double oldY = function(oldX);
            double x = oldX + step;
            double y;
            while(x<Math.PI+step)
            {
                y = function(x);
                DrawLine(xTrans(oldX), yTrans(oldY), xTrans(x), yTrans(y), color, 3);
                oldX = x;
                oldY = y;
                x += step;
            }
        }

        private void DrawLine(double x1, double y1, double x2, double y2, Color color, float thinkness)
        {
            Line line = new Line()
            {
                X1 = x1,
                Y1 = y1,
                X2 = x2,
                Y2 = y2,
                StrokeThickness = thinkness,
                Stroke = new SolidColorBrush(color)
            };

            Canvas.Children.Add(line);
        }

        private void Canvas_Loaded(object sender, RoutedEventArgs e)
        {
            Redraw();
        }

        private void BtnSinus_Click(object sender, RoutedEventArgs e)
        {
            function = Math.Sin;
            Redraw();
        }

        private void BtnCosinus_Click(object sender, RoutedEventArgs e)
        {
            function = Math.Cos;
            Redraw();
        }

        private void Window_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            Redraw();
        }
    }
}
Le code de tracé de nos courbes