IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C# Discussion :

Affichage et relation en binding entre des points et des arcs sur un canvas en WPF


Sujet :

C#

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2014
    Messages
    32
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Mars 2014
    Messages : 32
    Par défaut Affichage et relation en binding entre des points et des arcs sur un canvas en WPF
    Bonjour a tous,

    Alors dans le cadre d'un projet de travail, j'ai besoin de placer des points sur un canvas et de tracer des arecs et ces points.
    Un arc étant composé d'un point de départ et d'arrivée, ses coordonnées seront des pointeurs sur les points en question.
    Le stockage se ferait en collections de points et d'arcs.

    Je pense à faire deux classe : une point et une arc :
    La classe point étant composée des coordonnées X et Y, un numéro d'ID et un type.
    La classe arc d'un numéro d'ID et de deux pointeurs (point de départ et point d’arrivée )

    Lorsque je déplace un point à l'aide de la souris (ou en changeant les valeurs des coordonnées, l'arc doit suivre et l’affichage aussi.

    J'ai du mal avec la syntaxe du binding et aurait bien besoin de quelques conseils de votre part pour l’organisation de mon code ^^

    Voila merci de vos réponses les copains

  2. #2
    Membre extrêmement actif
    Inscrit en
    Avril 2008
    Messages
    2 573
    Détails du profil
    Informations personnelles :
    Âge : 65

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 573
    Par défaut
    bonjour

    Montre ton code des classes Points et ton xaml ...
    Et explique la finalite recherché dans ton projet .....
    Expose de cette facon ,je te renvoie en premier pour lire l'API wpf du class Path et PathGeometry pour voir ce qu'il necessite comme information pour dessiner un arc,la primitive WPF ArcSegment ayant ses propres exigences...

    bon code...

  3. #3
    Membre averti
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2014
    Messages
    32
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Mars 2014
    Messages : 32
    Par défaut
    Alors la finalité du projet est de pouvoir placer des points et des arcs en calque par dessus un image chargée dans le canvas(comme le plan d'un étage) afin de modeliser le plan sous forme filaire et d'enregistrer les coordonnées des différents points et arcs dans un fichier .txt ou .xml.

    Mon but est (lors d'un placement d'arc par exemple) : le premier clique crée un point à l'endroit du clic et le second en place un deuxième puis trace l'arc entre ces deux points.

    L'arc possède donc deux pointeurs (PointDebut et PointFin) qui pointent vers les coordonnées stockées dans les propriétés de la classe Point mais je n'arrive pas à faire le lien entre les deux .. cad entre le pointeur de l'arc et les coordonnées du point précédemment créé.

    Je dois afficher avoir une liste des Points et Arcs créés sur le canvas et les différentes propriétés des points et arcs affichées dans des textBox grâce au Binding.

    J' aimerais que lorsque je déplace un des points ou que je change ses coordonnées via une TextBox, l'affichage change et les valeurs des coordonnées aussi. Je sais que l'on peut le faire avec du Binding mais niveau syntaxe et déclaration du Binding je patauge un peu :/

    Mon code des classes Points et Arcs où il manque pas mal de choses ..
    Le Z est pour la hauteur du point



    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    public partial class Etages
        {
            public Etages()
            {
                int No_Etage;
                double Z_Etage;
     
                //Collection de points
                List<Noeuds> propNoeuds = new List<Noeuds>();
                propNoeuds.Add(new Noeuds() { Coord_X = 0, Coord_Y = 0, Coord_Z = 0, No_ID = 0, No_Etage = 0, Type "Normal" });
     
                //Collection d'arcs
                List<Arcs> propArcs = new List<Arcs>();
                propArcs.Add(new Arcs() { PointD_Coord_X = Noeuds.Coord_X, PointD_Coord_Y = Noeuds.Coord_Y, 
                    PointF_Coord_X = Noeuds.Coord_X, PointF_Coord_Y = Noeuds.Coord_Y, No_ID = 0, Type Normal });
     
     
            }
        }
     
     
        class Noeuds
        {
            //Declaration des differents parametres de la classe Noeuds
            public int No_ID { get; set; }
            public int No_Etage { get; set; }
            public int Coord_X { get; set; }
            public int Coord_Y { get; set; }
            public double Coord_Z { get; set; }
            enum Type {Normal, Escaliers, Ascenseur, Hall}
     
            public void Change_Z(double New_Z)
            {
                this.Coord_Z = New_Z;
            }
     
            public void AjoutPoint()
            {
     
            }
     
            public void SupprimePoint()
            {
     
            }
     
        }
     
        class Arcs
        {
            //Declaration des differents parametres de la classe Arcs
            public int No_ID { get; set; }
            public int No_Etage { get; set; }
            public int* PointD_Coord_X, PointD_Coord_Y, PointF_Coord_X, PointF_Coord_Y;
            public enum Type {Normal, Escaliers, Murs}
     
            public void AjoutArc()
            { 
     
            }
     
            public void SupprimeArc()
            { 
     
            }
     
        }

    Le code XAML

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    <Window x:Class="WpfApplication1.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="GogoTera" Height="495" Width="879" Name="GogoTera" Loaded="GogoTera_Loaded">
        <Grid>
            <Canvas Height="156" HorizontalAlignment="Left" Margin="405,50,0,0" Name="canvas1" VerticalAlignment="Top" Width="303" Background="LightYellow" PreviewMouseLeftButtonDown="canvas1_PreviewMouseLeftButtonDown" PreviewMouseMove="canvas1_PreviewMouseMove" PreviewMouseRightButtonDown="canvas1_PreviewMouseRightButtonDown" />
            <ListBox Height="100" HorizontalAlignment="Left" Margin="725,50,0,0" VerticalAlignment="Top" Width="120" Background="#FFE2C2C2" Name="lb_ListeNoeuds" />
            <ListBox Height="100" HorizontalAlignment="Left" Margin="725,181,0,0" VerticalAlignment="Top" Width="120" Name="lb_Liste_Arcs" Background="#FFE2C2C2" />
            <TextBox Height="23" HorizontalAlignment="Left" Margin="474,218,0,0" VerticalAlignment="Top" Width="120" Background="#FFE2D3D3" Name="tb_Coord_X" />
            <TextBox Height="23" HorizontalAlignment="Left" Margin="474,246,0,0" VerticalAlignment="Top" Width="120" Background="#FFE2D3D3" Name="tb_Coord_Y" />
            <TextBox Height="23" HorizontalAlignment="Left" Margin="474,275,0,0" VerticalAlignment="Top" Width="120" Background="#FFE2D3D3" Name="tb_Coord_Z" />
            <Label Content="X :" Height="28" HorizontalAlignment="Left" Margin="430,216,0,0" VerticalAlignment="Top" Name="Pos_X" />
            <Label Content="Y :" Height="28" HorizontalAlignment="Left" Margin="430,244,0,0" VerticalAlignment="Top" Name="Pos_Y" />
            <Label Content="Z :" Height="28" HorizontalAlignment="Left" Margin="430,273,0,0" VerticalAlignment="Top" Name="Pos_Z" />
            <Label Content="Liste Noeuds" Height="28" HorizontalAlignment="Left" Margin="743,26,0,0" VerticalAlignment="Top" />
            <Label Content="Liste Arcs" Height="28" HorizontalAlignment="Left" Margin="751,156,0,0" VerticalAlignment="Top" />
        </Grid>
    </Window>

  4. #4
    Membre extrêmement actif
    Inscrit en
    Avril 2008
    Messages
    2 573
    Détails du profil
    Informations personnelles :
    Âge : 65

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 573
    Par défaut
    bonjour

    Je vois ,tu veux gerer un Graph avec ses 2 DataNodes (ton class Point<=> DataNode) et ses DataArcs (ton class Arc=DataArc)...
    C'est faisable ,superpose sur un Image plan....
    Mais tu n'as pas repondu toujours à ma question sur la primitive graphique de l'Api ....

    Alors plus clairement tu dois fournir 2 petite precisions ...
    Comment veux-tu representer graphiquement
    1/ DataNode : carre(RectangleGeometry), cercle(ellipseGeometry),polygone (pathgeometry) ...

    2/DataArc :ligne droite(line), arc courbe(ArcSegment) ...

    Il est possible de faire un tel Graph-Chart avec binding sur un List<DataArc> ,modifiable sur saise dans des TextBox "biindes" à chaque DataArc et par dragging à la souris....

    Comme tu vois ,la balle est de ton cote ....
    Bon code...

  5. #5
    Membre averti
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2014
    Messages
    32
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Mars 2014
    Messages : 32
    Par défaut
    Et bien merci de ton aide pour commencer

    Et sinon oui, j'ai regardé l'API du class Path sur l'aide de microsoft qui explique comment tracer une ligne entre deux points.

    Tu parles bien de cela ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    <Canvas Height="300" Width="300">
     
      <!-- Draws a diagonal line from (10,10) to (50,50). -->
      <Line
        X1="10" Y1="10"
        X2="50" Y2="50"
        Stroke="Black"
        StrokeThickness="4" />
     
      <!-- Draws a diagonal line from (10,10) to (50,50)
           and moves it 100 pixels to the right. -->
      <Line
        X1="10" Y1="10"
        X2="50" Y2="50"
        StrokeThickness="4"
        Canvas.Left="100">
        <Line.Stroke>
          <RadialGradientBrush GradientOrigin="0.5,0.5" Center="0.5,0.5" RadiusX="0.5" RadiusY="0.5">
            <RadialGradientBrush.GradientStops>
              <GradientStop Color="Red" Offset="0" />
              <GradientStop Color="Blue" Offset="0.25" />
            </RadialGradientBrush.GradientStops>
          </RadialGradientBrush>
        </Line.Stroke>
      </Line>
     
      <!-- Draws a horizontal line from (10,60) to (150,60). -->
      <Line
         X1="10" Y1="60"
         X2="150" Y2="60"
         Stroke="Black"
         StrokeThickness="4"/>
     
    </Canvas>
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    // Add a Line Element
    myLine = new Line();
    myLine.Stroke = System.Windows.Media.Brushes.LightSteelBlue;
    myLine.X1 = 1;
    myLine.X2 = 50;
    myLine.Y1 = 1;
    myLine.Y2 = 50;
    myLine.HorizontalAlignment = HorizontalAlignment.Left;
    myLine.VerticalAlignment = VerticalAlignment.Center;
    myLine.StrokeThickness = 2;
    myGrid.Children.Add(myLine);
    Mais à part pour la ligne droite entre deux points le reste ne me servira pas je pense ..

    Alors au niveau de ma représentation graphique, j'ai juste besoin des points et des arcs(ligne droite uniquement), chacun stockées dès leurs création via la souris dans leur collection respective.

    Egalement en cliquant sur leur nom dans la listbox ou en les sélectionnant, d'afficher leur coordonnées dans les textbox.

    J'ai du mal a voir comment déclarer mes collections Noeuds et Arcs qui doivent faire partie d'un étage(pour les référence au Z) et en même temps que l'arcs point ses coordonnées sur celles de ses points ..

  6. #6
    Membre extrêmement actif
    Inscrit en
    Avril 2008
    Messages
    2 573
    Détails du profil
    Informations personnelles :
    Âge : 65

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 573
    Par défaut
    bonjour
    Ce type de structure signifie : q'un DataArc est defini par la donne de ses 2 DataNodes .
    Ceci entraine qu'une instance ArcData doit encapsule 2 DataNodes et c'est elle qu'il faut "binder"...

    Ta structure comportant 2 entites Data (Node et Arc) il faut les mapper à 2 primitives graphiques...
    Le DataNode a beau etre un point il faut l'afficher soit avec un rectangle ou un circle si on veut le voir ...d'ou :
    -Un EllipseGeometry pour le Node,car dote d'une prop Centre(Point).
    -LineGeometry pour l'Arc,car dote des props StartPoint et EndPoint(Point).
    Ces 2 objets sont encapsules chacun dans un Path qui leur fournit Stroke et le Fill ...

    le "mecanique" du Binding est illustre dans le premier exemple avec le Class Arc pour bien comprendre:
    1/Binding
    -du Linegeometry à un ArcData
    -de ses 2 EllipseGeometries aux 2 DataNodes
    -2 Labels aux No_Etage des 2 DataNodes
    2/Affichage des coords Point des 2 DataNodes dans des Textbox "Input User" bindes qui permettent d'entrer les X,Y directement .Comme ils sont "bindes" l'effet est immediat au changement de focus
    2/Manipulation des DataNodes à la souris
    -un CheckBox permet de passer du mode Drawing au Mode Selection...
    Dans le Mode Selection(Dragging) la souris est "capture" par le canvas et il faut terminer par click droit pour quitter ce mode...
    Dans le mode Drawing ,on voit "l'enfer" du code pour generer le LineGeometry et ses 2 EllipseGeometry....correspondant à l'ajout d'un Arc...

    Dans le 2eme Exemple plus corse :
    1/Utilisation d'un Observablecollection<Arc> Arcs qui supporte le changemeent de notification
    2/Un ListBox (qui est un itemsControl) :
    - son Items est binde à l' Observablecollection Arcs....
    - son ItemsPanel est un Canvas "hote" dont le background recevra ton Image Plan...
    - son ItemTemplate (comment doit s'afficher chaque ListBoxItem) est defini dans un DataTemplate etrangement semblable à celui du 1er Exemple
    - son ItemContainerStyle definit comme se positionne chaque ListBoxItem dans le Canvas hote...
    Ce style precise que ses props attaches Canvas.Left et Canvas.Top sont bindes aux Coords des 2 Nodes de l'Arc...

    3/DataTemplate de chaque ListBoxItem:
    -ressemble au DataTemplate du 1er Exemple mais le tout est wrappe dans un Panel de type Canvas car il faut un panel pour un DataTemplate qui comprend de nbreux elements ...
    Un Grid ,Stackpanel ne conviennent pas à cause des 2 TextBlocks qui servent au labeling des 2 Nodes ...
    Grace à ce DataTemplate ,on echappe à l' "l'enfer" du code utilise dans le 1er exemple pour les LineGeometry et autres EllipseGeometry....et on gere l'ajout d'un arc correspondant à la collection Arcs qui s'occupe de la "corvee"...


    Nota.Bene 1: pour ne pas introduire de "decalage" entre les cords saisies et le Image Plan les dimensions du "gridChart" (qui contient le Canvas "chart") doivent rester fixes ...A choisir d'une maniere approprie suivant les types d'image et l'affichage desiree...Si on veut zoomer ou dezoomer ,Emballer le "gridChart" dans un ViewBox....
    code behind .cs des class Node et Arc:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
     
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows;
    using System.ComponentModel;
     
    namespace WpfDataArcLine
    {
        public class Node:INotifyPropertyChanged
        {
            public Node()
            {
                No_Etage = 100;
                CoordP = new Point(150.0, 150.0);
                ID ="00";
            }
            public Node(int ONo_Etage, Point OCoordPoint,string OId)
                : this()
            {
                No_Etage = ONo_Etage;
                CoordP = OCoordPoint;
                ID = OId;
            }
            private int no_Etage ;
            public int No_Etage
            {
                get { return no_Etage; }
                set { no_Etage = value; RaisePropertyChanged("No_Etage"); }
            }
     
            private Point coordP;
            public Point CoordP
            {
                get { return coordP; }
                set { coordP = value; RaisePropertyChanged("CoordP"); }
            }
            private string id;
            public string ID
            {
                get { return id; }
                set { id = value; RaisePropertyChanged("ID"); }
            }
            public event PropertyChangedEventHandler PropertyChanged;
            private void RaisePropertyChanged(string propName)
            {
                PropertyChangedEventHandler h = PropertyChanged;
                if (h != null)
                    h(this, new PropertyChangedEventArgs(propName));
            }
        }
     
    }
    public class Arc : INotifyPropertyChanged
        {
            public Arc()
            {
                Node1 = new Node ();
                Node2 = new Node();
     
            }
            public Arc(Node ONode1,Node ONode2):this()
            {
                Node1 = ONode1;
                Node2 = ONode2;
     
            }
            private Node node1;
            public Node Node1
            {
                get { return node1; }
                set { node1 = value; RaisePropertyChanged("Node1"); }
            }
            private Node node2;
            public Node Node2
            {
                get { return node2; }
                set { node2 = value; RaisePropertyChanged("Node2"); }
            }
     
            public event PropertyChangedEventHandler PropertyChanged;
            private void RaisePropertyChanged(string propName)
            {
                PropertyChangedEventHandler h = PropertyChanged;
                if (h != null)
                    h(this, new PropertyChangedEventArgs(propName));
            }
        }
     
        public class Arcs : ObservableCollection<Arc>
        {
            Random rnd = new Random();
            Node nd1, nd2;
            Arc larc;
            double x,y;
            int etage,id;
            public Arcs()
            {
                for (int i = 1; i < 3; i++)
                {
                    x = rnd.Next(50,400);
                    y = rnd.Next(50,400);
                    Point p1 = new Point(x, y);
     
                    etage = rnd.Next(50, 100);
                    id = rnd.Next(100, 150); 
                    nd1 = new Node(etage, p1, id.ToString());
     
                    x = rnd.Next(100, 400);
                    y = rnd.Next(200, 400);
                    Point p2 = new Point(x, y);
                    etage = rnd.Next(80, 200);
                    id = rnd.Next(200, 300); 
                    nd2 = new Node(etage, p2,id.ToString());
     
     
                    larc = new Arc(nd1,nd2);
     
                    this.Add(larc);
                }
     
     
            }
        }
    code xaml du form (1er exemple):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    85
    86
    87
    88
    89
     
    <Window x:Class="WpfDataArcLine.WinSampleArc"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:local="clr-namespace:WpfDataArcLine"
            Title="WinSampleArc" Height="350" Width="525">
        <Window.Resources>
            <local:Arc x:Key="arc">
                <local:Arc.Node1 >
                    <local:Node CoordP="50,100"   No_Etage="40"/>
                </local:Arc.Node1>
                <local:Arc.Node2 >
                    <local:Node CoordP="150,200"   No_Etage="25"/>
                </local:Arc.Node2>
            </local:Arc>
        </Window.Resources>
        <Grid x:Name="mainGrid">
            <Grid.RowDefinitions>
                <RowDefinition Height="auto"></RowDefinition>
                <RowDefinition></RowDefinition>
            </Grid.RowDefinitions>
            <DockPanel x:Name="inputPanel" Grid.Row="0">
                <Label Content="Titre Chart Etages "  HorizontalContentAlignment="Center" Grid.Row="0" 
                   FontSize="16"
                   Background="Beige" />
                <Label Background="Azure" Content="Input Coord ND1 : "/>
                <TextBox x:Name="txtInputNode1" Text="{Binding Source={StaticResource arc},Path=Node1.CoordP,Mode=TwoWay}" ></TextBox>
                <Label Background="Azure" Content="Input Coord ND2 : "/>
                <TextBox x:Name="txtInputNode2" Text="{Binding Source={StaticResource arc},Path=Node2.CoordP,Mode=TwoWay}" ></TextBox>
                <CheckBox DockPanel.Dock="Bottom"  x:Name="chkDrawing" Content="CheckedDrawing/UnchekedSelecion" IsChecked="False" />
            </DockPanel>
     
            <Grid x:Name="gridChart"  Grid.Row="1" Height="700" Width="700">
                <Canvas 
                    x:Name="chart"
                    Background="LightBlue" 
                    ClipToBounds="True"
                    MouseLeftButtonDown="chart_MouseLeftButtonDown" 
                    MouseMove="chart_MouseMove" 
                    MouseRightButtonDown="chart_MouseRightButtonDown" >
                    <Path Stroke="Black" Fill="Yellow">
                        <Path.Data>
                            <EllipseGeometry 
                                x:Name="ellipseNode1" RadiusX="5" RadiusY="5" 
                                Center="{Binding Source={StaticResource arc},Path=Node1.CoordP,Mode=TwoWay}">
                            </EllipseGeometry>
                        </Path.Data>
                    </Path>
                    <Path Stroke="Black" Fill="Yellow">
                        <Path.Data>
                            <EllipseGeometry
                                x:Name="ellipseNode2" RadiusX="5" RadiusY="5" 
                                Center="{Binding Source={StaticResource arc}, Path=Node2.CoordP,Mode=TwoWay}">
                            </EllipseGeometry>
                        </Path.Data>
                    </Path>
                    <Path Stroke="blue" StrokeThickness="2">
                        <Path.Data >
                            <LineGeometry x:Name="arc"
                                StartPoint="{Binding Source={StaticResource arc}, Path=Node1.CoordP,Mode=TwoWay}"
                                EndPoint="{Binding Source={StaticResource arc}, Path=Node2.CoordP,Mode=TwoWay}">
                            </LineGeometry>
                        </Path.Data>
                    </Path>
                    <TextBlock  
                        x:Name="tbNode1"
                        Text="{Binding Source={StaticResource arc},Path=Node1.No_Etage,Mode=TwoWay}" 
                        Canvas.Left="{Binding Source={StaticResource arc},Path=Node1.CoordP.X}"
                        Canvas.Top ="{Binding Source={StaticResource arc},Path=Node1.CoordP.Y}"/>
     
                    <TextBlock 
                        x:Name="tbNode2"
                        Text="{Binding Source={StaticResource arc},Path=Node2.CoordP,Mode=TwoWay}" 
                        Canvas.Left="{Binding Source={StaticResource arc},Path=Node2.CoordP.X}"
                        Canvas.Top ="{Binding Source={StaticResource arc},Path=Node2.CoordP.Y}"/>
     
     
                    <!--LineGeometry de l'API avec l'infrastructure necessaire à gerer-->
                    <Path Stroke="Red" StrokeThickness="2">
                        <Path.Data>
                            <LineGeometry  StartPoint="50,200" EndPoint="140,100"/>
                        </Path.Data>
                    </Path>
                </Canvas>
            </Grid >
     
     
        </Grid>
    </Window>
    code behind .cs du form(1er exemple):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
     
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Shapes;
     
    namespace WpfDataArcLine
    {
        /// <summary>
        /// Logique d'interaction pour WinSampleArc.xaml
        /// </summary>
        public partial class WinSampleArc : Window
        {
            public WinSampleArc()
            {
                InitializeComponent();
            }
            //variables drawing
            private bool ModeDrawing = false;
            private bool ModeDragging = false;
            private Path pathNode1 = null;
            private Path pathNode2 = null;
            private Path pathArc = null;
            private Arc larc = null;
            //variables dragging
            private Path selectedPath = null;
            private EllipseGeometry selectedEllipseNode = null;
            private Brush prevFill = null;
            private void chart_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
            {
                Canvas cnv = sender as Canvas;
                Point ptDown = Mouse.GetPosition(cnv);
                bool b = (bool)chkDrawing.IsChecked;
                ModeDrawing = b;
                ModeDragging = !b;
                if (ModeDrawing && e.LeftButton == MouseButtonState.Pressed)
                {
                    larc = new Arc();
                    larc.Node1 = new Node(25, ptDown,"0101");
                    larc.Node2 = new Node(45, ptDown,"0105");
     
                    pathNode1 = GetPathNode1(larc);
                    pathNode2 = GetPathNode2(larc);
                    pathArc = GetPathArc(larc);
                    this.chart.Children.Add(pathNode1);
                    this.chart.Children.Add(pathNode2);
                    this.chart.Children.Add(pathArc);
     
     
                }
                else if (ModeDragging)
                {
                    UIElement elem = e.Source as UIElement;
                    if (elem.GetType() == typeof(Path))
                    {
                        ptDown = Mouse.GetPosition(cnv);
                        selectedPath = (Path)elem;
                        prevFill = selectedPath.Fill;
                        selectedEllipseNode = selectedPath.Data as EllipseGeometry;
                        if (selectedEllipseNode == null) return;
     
                        cnv.CaptureMouse();
                        selectedPath.Fill = Brushes.Magenta;
                        cnv.CaptureMouse();
                    }
                }
            }
     
            private void chart_MouseMove(object sender, MouseEventArgs e)
            {
                Canvas cnv = sender as Canvas;
                Point ptMove = Mouse.GetPosition(cnv);
                if (ModeDrawing && e.LeftButton == MouseButtonState.Pressed)
                {
                    if (larc != null) larc.Node2.CoordP = ptMove;
     
                }
                else if (ModeDragging && e.LeftButton == MouseButtonState.Pressed)
                {
                    if (selectedEllipseNode != null)
                    {
                        selectedEllipseNode.Center = ptMove;
     
                    }
                }
     
            }
     
            private void chart_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
            {
                Canvas cnv = sender as Canvas;
                Point pt = Mouse.GetPosition(cnv);
                if (ModeDrawing)
                {
                    larc.Node2.CoordP = pt;
     
                    larc = null;
                    pathNode1 = null;
                    pathNode2 = null;
                    pathArc = null;
                }
                else if (ModeDragging)
                {
                    if (selectedEllipseNode != null)
                    {
                        selectedEllipseNode.Center = pt;
                        selectedPath.Fill = prevFill;
                        selectedPath = null;
                        selectedEllipseNode = null;
                        cnv.ReleaseMouseCapture();
                    }
                }
            }
            private Path GetPathNode1(Arc narc)
            {
     
                EllipseGeometry ellip = new EllipseGeometry();
                ellip.RadiusX = 5; ellip.RadiusY = 5;
                Binding bd = new Binding("Node1.CoordP");
                bd.Source = narc;
                bd.Mode = BindingMode.TwoWay;
                BindingOperations.SetBinding(ellip, EllipseGeometry.CenterProperty, bd);
     
                Path pathNode = new Path();
                pathNode.Stroke = Brushes.Black;
                pathNode.StrokeThickness = 2.0;
                pathNode.Fill = Brushes.Aquamarine;
                pathNode.Data = ellip;
     
                return pathNode;
            }
            private Path GetPathNode2(Arc narc)
            {
     
                EllipseGeometry ellip = new EllipseGeometry();
                ellip.RadiusX = 5; ellip.RadiusY = 5;
                Binding bd = new Binding("Node2.CoordP");
                bd.Source = narc;
                bd.Mode = BindingMode.TwoWay;
                BindingOperations.SetBinding(ellip, EllipseGeometry.CenterProperty, bd);
     
     
                Path pathNode = new Path();
                pathNode.Stroke = Brushes.Black;
                pathNode.StrokeThickness = 2.0;
                pathNode.Fill = Brushes.Pink;
                pathNode.StrokeThickness = 2.0; pathNode.Data = ellip;
     
     
     
                return pathNode;
            }
            private Path GetPathArc(Arc narc)
            {
                Binding bd;
                LineGeometry arcGeom = new LineGeometry();
                bd = new Binding("Node1.CoordP");
                bd.Source = narc;
                bd.Mode = BindingMode.TwoWay;
                BindingOperations.SetBinding(arcGeom, LineGeometry.StartPointProperty, bd);
                bd = new Binding("Node2.CoordP");
                bd.Source = narc;
                bd.Mode = BindingMode.TwoWay;
                BindingOperations.SetBinding(arcGeom, LineGeometry.EndPointProperty , bd);
     
     
     
                Path pathArc = new Path();
                pathArc.Stroke = Brushes.Black;
                pathArc.StrokeThickness = 2.0;
                pathArc.Data = arcGeom ;
     
     
     
                return pathArc;
            }
        }
    }
    code xaml du form (2e exemple):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
     
    <Window x:Class="WpfDataArcLine.WinMoreArcs"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:local="clr-namespace:WpfDataArcLine"
            Title="WinMoreArcs" Height="350" Width="525">
        <Window.Resources>
            <local:Arcs x:Key="arcs"></local:Arcs>
            <DataTemplate
                x:Key="dt"
                DataType="{x:Type local:Arc}">
                <Canvas>
                    <Path Stroke="Black" Fill="Yellow" >
                        <Path.Data>
                            <EllipseGeometry 
                                x:Name="ellipseNode1" RadiusX="5" RadiusY="5" 
                                Center="{Binding Path=Node1.CoordP,Mode=TwoWay}">
                            </EllipseGeometry>
                        </Path.Data>
                    </Path>
                    <Path Stroke="Black" Fill="Yellow" >
                        <Path.Data>
                            <EllipseGeometry
                                x:Name="ellipseNode2" RadiusX="5" RadiusY="5" 
                                Center="{Binding  Path=Node2.CoordP,Mode=TwoWay}">
                            </EllipseGeometry>
                        </Path.Data>
                    </Path>
                    <Path Stroke="Blue" StrokeThickness="2">
                        <Path.Data>
                            <LineGeometry x:Name="arc" 
                                StartPoint="{Binding Path=Node1.CoordP,Mode=TwoWay}"
                                EndPoint="{Binding  Path=Node2.CoordP,Mode=TwoWay}">
                            </LineGeometry>
                        </Path.Data>
                    </Path>
                    <TextBlock 
                        x:Name="tbNode1"
                        Background="Red" Foreground="White" 
                        Text="{Binding Path=Node1.No_Etage,Mode=TwoWay}" 
                        Canvas.Left="{Binding Path=Node1.CoordP.X,Mode=TwoWay }"
                        Canvas.Top ="{Binding Path=Node1.CoordP.Y,Mode=TwoWay }"/>
     
                    <!--on affiche Node2.CoordP (au lieu du Numero Etage) pour "voir" le fonctionnemt du binding-->
                    <TextBlock 
                        x:Name="tbNode2"
                        Background="Red" Foreground="White" 
                        Text="{Binding Path=Node2.CoordP,Mode=TwoWay}" 
                        Canvas.Left="{Binding Path=Node2.CoordP.X,Mode=TwoWay }"  
                        Canvas.Top ="{Binding Path=Node2.CoordP.Y,Mode=TwoWay }"/>
                </Canvas>
            </DataTemplate>
        </Window.Resources>
        <Grid x:Name="mainGrid">
            <Grid.RowDefinitions>
                <RowDefinition Height="auto"></RowDefinition>
                <RowDefinition ></RowDefinition>
            </Grid.RowDefinitions>
            <DockPanel x:Name="inputPanel" Grid.Row="0">
                <Label Content="Titre Chart Etages "  HorizontalContentAlignment="Center" Grid.Row="0" 
                   FontSize="16"
                   Background="Beige" />
                <Label Background="Azure" Content="Input Coord ND1 : "/>
                <TextBox x:Name="txtInputNode1" Text="{Binding Source={StaticResource arcs}, Path=Node1.CoordP, Mode=TwoWay}" ></TextBox>
                <Label Background="Azure" Content="Input Coord ND2 : "/>
                <TextBox x:Name="txtInputNode2" Text="{Binding Source={StaticResource arcs},Path=Node2.CoordP, Mode=TwoWay}" ></TextBox>
                <CheckBox x:Name="chkDrawing" Content="CheckedDrawing/UnchekedSelecion" IsChecked="False" />
            </DockPanel>
            <!--IsSynchronizedWithCurrentItem="true":synchronisation avec l'item courant-->
            <!--image etage dans background du canvas "calque d'arriere plan"-->
            <!--utilise le PreviewMouseLeftButtonDown etc ...-->
            <!--veuillez à fixer un Height & Width appropries du Grid chart  ...-->
            <!--l'image plan garde un size constant =>les coord canvas sont relatives à ce size...-->
     
            <Grid x:Name="gridChart"  Grid.Row="1" Height="700" Width="700">
                    <ListBox 
                        x:Name="ListBox1"
                        IsSynchronizedWithCurrentItem="true"
                        ItemTemplate="{StaticResource dt}"
                        ItemsSource="{Binding Source={StaticResource arcs}}" >
                        <ItemsControl.ItemsPanel>
                            <ItemsPanelTemplate>
                                <Canvas
                                    IsItemsHost="true" 
                                    ClipToBounds="True"
                                    PreviewMouseLeftButtonDown="Canvas_PreviewMouseLeftButtonDown"
                                    MouseMove="Canvas_MouseMove" 
                                    PreviewMouseRightButtonDown="Canvas_PreviewMouseRightButtonDown">
                                    <Canvas.Background>
                                        <ImageBrush 
                                            Stretch="UniformToFill" 
                                            ImageSource="Resources/Plan.jpg"/>
                                    </Canvas.Background>
                                </Canvas>
                            </ItemsPanelTemplate>
                        </ItemsControl.ItemsPanel>
                        <ItemsControl.ItemContainerStyle>
                            <Style TargetType="ListBoxItem">
                                <Setter Property="Canvas.Left" Value="{Binding Path=Arc.Node1.CoordP.X}"/>
                                <Setter Property="Canvas.Top" Value="{Binding Path=Arc.Node1.CoordP.Y}"/>
                            </Style>
                        </ItemsControl.ItemContainerStyle>
                </ListBox>
            </Grid>
     
     
        </Grid>
    </Window>
    code behind .cs du form(2e exemple):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
     
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Shapes;
     
    namespace WpfDataArcLine
    {
        /// <summary>
        /// Logique d'interaction pour WinMoreArcs.xaml
        /// </summary>
        public partial class WinMoreArcs : Window
        {
            public WinMoreArcs()
            {
                InitializeComponent();
            }
            //variables drawing
            private bool ModeDrawing = false;
            private bool ModeDragging = false;
            private Arc larc = null;
     
            //variables dragging
            private Path selectedPath = null;
            private EllipseGeometry selectedEllipseNode = null;
            private Brush prevFill = null;
            private void Canvas_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
            {
                Canvas cnv = sender as Canvas;
                UIElement elem = e.OriginalSource as UIElement; //note la difference avec SampleArc
                Point   ptDown = Mouse.GetPosition(cnv);
     
                bool b = (bool)chkDrawing.IsChecked;
                ModeDrawing = b;
                ModeDragging = !b;
                if (ModeDrawing && e.LeftButton == MouseButtonState.Pressed)
                {
                    larc = new Arc();
                    larc.Node1 = new Node(25, ptDown,"0101");
                    larc.Node2 = new Node(45, ptDown,"0102");
                    Arcs list = (Arcs)ListBox1.ItemsSource;
                    list.Add(larc);
     
                }
                else if (ModeDragging)
                {
     
                    if (elem.GetType() == typeof(Path))
                    {
     
                        selectedPath = (Path)elem;
                        prevFill = selectedPath.Fill;
                        selectedEllipseNode = selectedPath.Data as EllipseGeometry;
                        if (selectedEllipseNode == null) return;
     
                        selectedPath.Fill = Brushes.Magenta;
                        cnv.CaptureMouse();
                    }
                }
            }
     
            private void Canvas_MouseMove(object sender, MouseEventArgs e)
            {
                Canvas cnv = sender as Canvas;
                Point ptMove = Mouse.GetPosition(cnv);
                if (ModeDrawing && e.LeftButton == MouseButtonState.Pressed)
                {
                    if (larc != null) larc.Node2.CoordP = ptMove;
     
                }
                else if (ModeDragging && e.LeftButton == MouseButtonState.Pressed)
                {
                    if (selectedEllipseNode != null)
                    {
                        selectedEllipseNode.Center = ptMove;
     
                    }
                }
     
            }
     
            private void Canvas_PreviewMouseRightButtonDown(object sender, MouseButtonEventArgs e)
            {
                Canvas cnv = sender as Canvas;
                Point pt = Mouse.GetPosition(cnv);
                if (ModeDrawing && larc !=null )
                {
                    larc.Node2.CoordP = pt;
                    larc = null;
     
                }
                else if (ModeDragging)
                {
                    if (selectedEllipseNode != null)
                    {
                        selectedEllipseNode.Center = pt;
                        selectedPath.Fill = prevFill;
                        selectedPath = null;
                        selectedEllipseNode = null;
                        cnv.ReleaseMouseCapture();
     
                    }
                }
            }
        }
    }
    bon code...

Discussions similaires

  1. [Débutant] Calculer un angle entre 3 points avec des coordonnées X Y Z
    Par mattparla dans le forum MATLAB
    Réponses: 6
    Dernier message: 28/11/2009, 17h43
  2. Réponses: 5
    Dernier message: 23/07/2009, 19h49
  3. Comment changer des virgules par des points
    Par solorac dans le forum Excel
    Réponses: 2
    Dernier message: 30/07/2007, 10h38
  4. Réponses: 24
    Dernier message: 01/06/2007, 21h37
  5. [ plugin ][ extension point ] liste des points d'extension
    Par Satch dans le forum Eclipse Java
    Réponses: 1
    Dernier message: 19/03/2004, 09h34

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo