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

Windows Presentation Foundation Discussion :

Path vs PathGeometry dans DataTemplate


Sujet :

Windows Presentation Foundation

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Inscrit en
    Septembre 2006
    Messages
    232
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 232
    Par défaut Path vs PathGeometry dans DataTemplate
    bonjour

    je template ma ListBox alors plusieurs possibilités :
    1. faire la différence entre mes Items par leur Type et là j'utilise un TargetType
    2. utiliser un TemplateSelector..inconvénient il est appelé un seule fois au chargement, donc pas trop dynamique.
    3. comme la différence est dans la géométrie a dessiner j'utilise cette dernière méthode avec un seule DataTemplate mais en faisant un Binding sur Path qui est normalement un type Shape


    mais j'ai utilisé dans ma geometrie en code behind un PathGeometry

    ma question est : pourquoi un PathGeometry puise être accepté dans mon XAML au niveau du binding suivant :

    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
    <DataTemplate   x:Key="viewpath"   >
     
                <Canvas Name="itemcanvas" Background="Transparent" 
                        PreviewMouseMove="itemcanvas_PreviewMouseMove"
                        PreviewMouseLeftButtonDown="itemcanvas_PreviewMouseLeftButtonDown"
                        PreviewMouseLeftButtonUp="itemcanvas_PreviewMouseLeftButtonUp"     >
                    <Path x:Name="pathnode" Stroke="Green" Fill="Black" Data="{Binding Path=geoview1.geometryform, Mode=TwoWay}"></Path>
     
                </Canvas>
     
                <DataTemplate.Triggers>
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter TargetName="pathnode" Property="Fill" Value="red"/>
                    </Trigger>
                </DataTemplate.Triggers>
     
            </DataTemplate>
    sa me dessine deux triangles comme il faut, il y a même mon Trigger qui fonctionne normalement.

    ma classe :

    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
     
     public class GeomView : INotifyPropertyChanged
        { 
     
    //......
     
     public PathGeometry geometryform
            {
                get { return this._geometryform; }
     
                set
                {
                    if (value != this._geometryform)
                    {
                        this._geometryform = value;
                        OnPropertyChanged(nameof(this.geometryform));
                    }
                }
     
     
     
            }
     
     
     
    }

  2. #2
    Membre Expert
    Homme Profil pro
    edi
    Inscrit en
    Juin 2007
    Messages
    941
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : edi

    Informations forums :
    Inscription : Juin 2007
    Messages : 941
    Par défaut
    Qu'est-ce-qui t'intrigue ? Un objet Path peut recevoir dans sa propriété Data un Binding sur (entre autres) un objet PathGeometry à partir duquel il va réaliser son dessin, c'est tout simplement dans la conception de la classe :
    https://msdn.microsoft.com/en-us/lib...(v=vs.90).aspx

  3. #3
    Membre éclairé
    Inscrit en
    Septembre 2006
    Messages
    232
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 232
    Par défaut
    ce qui ma intrigué est que Path est un System.Windows.Shapes alors que PathGeometry est un System.Windows.Media, car pour faire du drag and drop je doit caster le sender de Path à PathGeometry et mon objet ne bouge pas je me dit que mon problème vient d'un problème de Type ?!:

    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
     
            private Path selPath = null;
            private PathGeometry pg1 = null;
            private bool dragmod = false; //not yet used
            Point p0, p1;
            double dx, dy;
     
            private void itemcanvas_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
            {
                Canvas cn;
                cn = (sender as Canvas);
                selPath = new Path();
                selPath = EnumVisual(cn) as Path;
                pg1 = selPath.Data as PathGeometry;
                p0 = e.GetPosition(cn);
            }
     
            private void itemcanvas_PreviewMouseMove(object sender, MouseEventArgs e)
            {
                if (selPath!=null)
                {
                    Canvas cn;
                    cn = (sender as Canvas);
                    p1 = e.GetPosition(cn);
                    dx = p1.X - p0.X;
                    dy = p1.Y - p0.Y;
                    TransletPath(pg1, dx, dy);
                    p0 = p1;
     
                   //this.txb1.Text = "dx: "+dx.ToString()+"dy:  "+dy.ToString();
                }
            }
     
            private void itemcanvas_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
            {
                if (selPath == null) return;
     
                //liberer la capture souris par un click droit 
                //selPath.ReleaseMouseCapture();
     
                selPath = null;
     
            }
     
     
     
     
            public void TransletPath(PathGeometry mypt,double dltx , double dlty)
            {
     
                TranslateTransform Tr = new TranslateTransform(dltx, dlty);
                pg1.Transform = Tr;
     
                //mypt.Transform= new TranslateTransform(dltx, dlty);
                //Canvas ss = mypt.Parent as Canvas;
                //double xx = Canvas.GetLeft(mypt);
                //double yy = Canvas.GetTop(mypt);
                //Canvas.SetLeft(mypt, Canvas.GetLeft(mypt) + dltx)
                //Canvas.SetTop(mypt, Canvas.GetTop(mypt) + dlty);
     
            }
     
     
     
            static public Visual EnumVisual(Visual myVisual)
            {
                for (int i = 0; i < VisualTreeHelper.GetChildrenCount(myVisual); i++)
                {
                    // Retrieve child visual at specified index value.
                    Visual childVisual = (Visual)VisualTreeHelper.GetChild(myVisual, i);
     
                    if (childVisual.GetType()== typeof(Path))
                    {
                        return childVisual;
                    }
     
                    // Enumerate children of the child visual object.
                    EnumVisual(childVisual);
                }
                return myVisual;
            }

  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

    Non ,ton probleme vient de la comprehension de l'API WPF...

    Path est un UIElement donc il reagit aux events clavier et souris ...
    PathGeometry et autres geometries sont des elements graphiques insensibles aux events.
    Ils sont simplement dessinés dans Path qui leur sert de conteneur comme le Canvas sert de conteneur au Path)...

    1/ Pour déplacer un Path y compris son PathGeometry (qui est unique,faut-il le rappeler) relativement à son "conteneur" Canvas ,tu disposes de Canvas.SetLeft,Canvas.SetTop...

    2/ Pour déplacer le PathGeometry relativement à son "conteneur" Path ,tu disposes :
    - de Transformation....
    - la propriété Stretch du Path doit être mise à None (voir exemple ci-après)...

    3/Pour changer la Géométrie (points) du PathGeometry il faut parcourir dans une double boucle "foreach" sa collection PathGeometry.Figures et ensuite la collection Figure.Segments de chaque Figure ,déterminer le type (arcsegment, linesegment etc...) et caster dans une variable approprie ...

    code exemple 1 qui déplace le Path relativement à Canvas:
    code XAML du Form:
    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
     
    <Window x:Class="WpfPath.Window1"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="Window1" Height="350" Width="525">
        <Grid>
            <Canvas x:Name="ItemCanvas" ClipToBounds="True" Background="LightGray" 
                    Loaded="ItemCanvas_Loaded"
                    PreviewMouseLeftButtonDown="ItemCanvas_PreviewMouseLeftButtonDown"
                    PreviewMouseMove="ItemCanvas_PreviewMouseMove" 
                    PreviewMouseRightButtonDown="ItemCanvas_PreviewMouseRightButtonDown"
                    >
                <Path  Stroke="BlueViolet" StrokeThickness="3"
                      Canvas.Left="75" Canvas.Top="85"
                      >
                    <Path.Data>
                        <PathGeometry>
                            <PathFigure StartPoint="100,100">
                                <LineSegment Point="150,50" IsStroked="True" />
                                <ArcSegment Point="200,100" Size="50,50" IsLargeArc="False"  RotationAngle="0" SweepDirection="Clockwise" IsStroked="True" IsSmoothJoin="True"/>
                            </PathFigure>
                        </PathGeometry>
                    </Path.Data>
     
                </Path>
            </Canvas>
        </Grid>
    </Window>
    et son code behind.cs :

    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
     
    namespace WpfPath
    {
        /// <summary>
        /// Logique d'interaction pour Window1.xaml
        /// </summary>
        public partial class Window1 : Window
        {
            private Rectangle limitRect = new Rectangle();//rectangle de limites du Path
            public Window1()
            {
                InitializeComponent();
            }
            private void ItemCanvas_Loaded(object sender, RoutedEventArgs e)
            {
                limitRect.Stroke = Brushes.Yellow ;
                ItemCanvas.Children.Add(limitRect);
            }
            private Path selPath = null;
            Point startPoint;
            double dx, dy;
            private void ItemCanvas_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
            {
                FrameworkElement elem = e.OriginalSource as FrameworkElement;//uielement cliqué
                if (elem == null) return;
     
                if (elem.GetType() != typeof(Path)) return;// pas de type Path ?
                selPath = elem as Path;
                limitRect.Width = selPath.ActualWidth; //display du limitRect superposé au path
                limitRect.Height = selPath.ActualHeight;
                Canvas.SetLeft(limitRect, Canvas.GetLeft(selPath));
                Canvas.SetTop(limitRect, Canvas.GetTop(selPath));
     
                selPath.CaptureMouse();
                startPoint = e.GetPosition(selPath);
     
            }
     
            private void ItemCanvas_PreviewMouseMove(object sender, MouseEventArgs e)
            {
                if (selPath  != null)
                {
     
     
                    Point p = e.GetPosition(selPath);
                    dx = p.X - startPoint.X;
                    dy = p.Y - startPoint.Y;
                    Canvas.SetLeft(selPath, Canvas.GetLeft(selPath) + dx);
                    Canvas.SetTop(selPath, Canvas.GetTop(selPath) + dy);
     
                    Canvas.SetLeft(limitRect, Canvas.GetLeft(selPath));
                    Canvas.SetTop(limitRect, Canvas.GetTop(selPath));
     
     
     
                }
            }
     
            private void ItemCanvas_PreviewMouseRightButtonDown(object sender, MouseButtonEventArgs e)
            {
                if (selPath != null)
     
                //liberer la capture souris par un click droit 
                selPath.ReleaseMouseCapture();
                selPath = null;
                limitRect.Width = 0.0;
                limitRect.Height = 0.0;
     
            }
     
     
        }
    }
    code exemple 2 qui déplace le PathGeometry relativement à Path:
    code XAML du Form:
    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
     
    <Window x:Class="WpfPath.Window2"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="Window2" Height="350" Width="525">
        <Grid>
            <Canvas x:Name="ItemCanvas" ClipToBounds="True" Background="LightGray" 
                    Loaded="ItemCanvas_Loaded"
                    PreviewMouseLeftButtonDown="ItemCanvas_PreviewMouseLeftButtonDown"
                    PreviewMouseMove="ItemCanvas_PreviewMouseMove" 
                    PreviewMouseRightButtonDown="ItemCanvas_PreviewMouseRightButtonDown"
                    >
                <Path  Stroke="BlueViolet" StrokeThickness="3"
                      Canvas.Left="75" Canvas.Top="85"
                      Stretch="None">
                    <Path.Data>
     
                        <PathGeometry>
                            <PathFigure StartPoint="100,100">
                                <LineSegment Point="150,50" IsStroked="True"  />
                                <ArcSegment Point="200,100" Size="50,50" IsLargeArc="False"  RotationAngle="0" SweepDirection="Clockwise" IsStroked="True" IsSmoothJoin="True"/>
                            </PathFigure>
                        </PathGeometry>
                    </Path.Data>
     
                </Path>
            </Canvas>
        </Grid>
    </Window>
    et son code behind.cs :

    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
     
    namespace WpfPath
    {
        /// <summary>
        /// Logique d'interaction pour Window2.xaml
        /// </summary>
        public partial class Window2 : Window
        {
            private Rectangle limitRect = new Rectangle();//rectangle de limites du Path
            public Window2()
            {
                InitializeComponent();
            }
            private void ItemCanvas_Loaded(object sender, RoutedEventArgs e)
            {
                limitRect.Stroke = Brushes.Yellow;
                ItemCanvas.Children.Add(limitRect);
            }
            private Path selPath = null;
            private PathGeometry selGeom = null;
            Point startPoint;
            double dx, dy;
     
            private void ItemCanvas_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
            {
                FrameworkElement elem = e.OriginalSource as FrameworkElement;//uielement cliqué
                if(elem == null )return ;
     
                if (elem.GetType() != typeof(Path))return ;// pas de type Path
                selPath = elem as Path;
     
                limitRect.Width = selPath.ActualWidth;//display du limitRect superposé au path
                limitRect.Height=selPath.ActualHeight ;
                Canvas.SetLeft(limitRect, Canvas.GetLeft(selPath));
                Canvas.SetTop(limitRect, Canvas.GetTop(selPath));
     
                Geometry elemGeom = selPath.Data as Geometry;//elem geometry
                if (elemGeom == null) return ;
     
                if (elemGeom.GetType() == typeof(PathGeometry))  // de type PathGeometry ? (il existe aussi EllipseGeometry,StreamGeometry etc...)
                {
                    selGeom = elemGeom as PathGeometry;
                    selPath.CaptureMouse();
                    startPoint = e.GetPosition( selPath);
     
                }
     
     
            }
     
            private void ItemCanvas_PreviewMouseMove(object sender, MouseEventArgs e)
            {
                if (selGeom != null)
                {
     
     
                    Point p = e.GetPosition(selPath );
                    dx = p.X - startPoint.X;
                    dy = p.Y - startPoint.Y;
     
                    selGeom.Transform = new TranslateTransform(dx, dy);
     
     
                    Canvas.SetLeft(limitRect, Canvas.GetLeft(selPath));
                    Canvas.SetTop(limitRect, Canvas.GetTop(selPath));
     
                }
     
            }
     
            private void ItemCanvas_PreviewMouseRightButtonDown(object sender, MouseButtonEventArgs e)
            {
                if (selGeom != null)
     
                //liberer la capture souris par un click droit 
                selPath.ReleaseMouseCapture();
                selGeom = null;
                selPath = null;
                limitRect.Width = 0.0;
                limitRect.Height = 0.0;
            }
     
     
        }
    }
    bon code...

  5. #5
    Membre éclairé
    Inscrit en
    Septembre 2006
    Messages
    232
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 232
    Par défaut
    merci pour ta réponse :
    Citation Envoyé par MABROUKI Voir le message

    2/ Pour déplacer le PathGeometry relativement à son "conteneur" Path ,tu disposes :
    - de Transformation....
    - la propriété Stretch du Path doit être mise à None (voir exemple ci-après)...
    c'est ça puisque je fait un binding (mon Data = "ma prop PathGeometry ") et donc je modifie par le code le PathGeometry pour cela j'utilise "Transformation"

    je vais corriger mon code

  6. #6
    Membre éclairé
    Inscrit en
    Septembre 2006
    Messages
    232
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 232
    Par défaut
    bonjour

    en utilisant :

    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
    private void ItemCanvas_PreviewMouseMove(object sender, MouseEventArgs e)
            {
                if (selGeom != null)
                {
     
     
                    Point p = e.GetPosition(selPath );
                    dx = p.X - startPoint.X;
                    dy = p.Y - startPoint.Y;
     
                    selGeom.Transform = new TranslateTransform(dx, dy);
     
                }
     
            }
    sa marche la première fois pas la deuxième!! sa donne des sauts de mouvement et vers les mauvaises directions , je crois que Transform sauvegarde la dernière transformation, alors j'ai fais ceci :


    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
    private void itemcanvas_PreviewMouseMove(object sender, MouseEventArgs e)
            {
                if (selPath!=null)
                {
                    
                    p1 = e.GetPosition(selPath);
                    dx  =p1.X - p0.X;
                    dy  = p1.Y - p0.Y;
                    pg1.Transform = new TranslateTransform(dx+ pg1.Transform.Value.OffsetX, dy+ pg1.Transform.Value.OffsetY);
                    p0 = p1;
                   
                   
                }
            }
    j'ai "découvert" en faisant un test sur un autre canvas :

    en cliquant sur un bouton je déplace un rectangle

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    int delt = 0;
            private void but1_Click(object sender, RoutedEventArgs e)
            {
                delt = delt + 1;
                Path mylocalpt = this.mycanvas.Children[0] as Path;
                mylocalpt.Data.Transform= new TranslateTransform(100 , 100);               //mouvement une seule fois meme si je continu à cliquer
               // mylocalpt.Data.Transform= new TranslateTransform(10+delt , 10+delt);  // mouvement en continu pour chaque clique 
                
            }

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Class-Path qui disparaît dans MANIFEST.MF
    Par Bash01 dans le forum Général Java
    Réponses: 1
    Dernier message: 24/04/2013, 12h24
  2. [Débutant] Path Dll mobile dans Dllimport
    Par cdumargu dans le forum C#
    Réponses: 21
    Dernier message: 02/02/2012, 14h36
  3. Source d'une Image dans DataTemplate
    Par jeanjean40 dans le forum Silverlight
    Réponses: 6
    Dernier message: 18/08/2011, 17h37
  4. Modifier le path des images dans jquery-ui.css
    Par bertrand0756 dans le forum jQuery
    Réponses: 1
    Dernier message: 13/06/2011, 17h47
  5. Réponses: 1
    Dernier message: 06/11/2008, 13h02

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