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 :

[Matrix] ou comment se faire un film


Sujet :

Windows Presentation Foundation

  1. #1
    Membre expérimenté
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 562
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 562
    Points : 1 313
    Points
    1 313
    Par défaut [Matrix] ou comment se faire un film
    hello (excusez la vanne sur matrix )

    bon voila je reccup une MatrixTransform
    avec les valeurs suivante

    M11 0.571584699453553
    M12 0.0
    M21 0.0
    M22 0.571584699453553
    OffsetX 184.0
    OffsetY 118.71256830601092

    avec un coef de zoom de 57 % donc tout vas bien
    puisque M11 et M22 donne le zoom

    si j'applique une rotation de -45° sur l'element j'ai alors

    M11 0.404171417006082
    M12 -0.40417141700608195
    M21 0.40417141700608195
    M22 0.404171417006082
    OffsetX 166.69226289657158
    OffsetY 228.39794001211757

    le M11 et M22 changent alors que normalement ca correspond au ceof de zoom je comprend pas trop

    les offsets sont bon mais pas le zoom et on a une inclinaison qui a changé

    j'aimerais savoir si on peut a partir de M11 et M12 (eventuellement M21 et M22)
    determiner l"angle de rotation et le coeficient de zoom correcte
    IKEAS : Finalement je crois que c'est dans ses faiblesses que l'on y trouve a la fois de la force et a la fois de la richesse...
    ----------------------------------------------------
    Si vous avez du taf en wpf & design d'application sympa, contactez moi !!!!
    http://ultimatecorp.eu/wpf/

  2. #2
    Expert confirmé
    Inscrit en
    Avril 2008
    Messages
    2 564
    Détails du profil
    Informations personnelles :
    Âge : 64

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 564
    Points : 4 441
    Points
    4 441
    Par défaut
    bonjour ikeas....
    Vu la definition meme des operations matricielles(mul,add) on ne peut determiner à partir de la valeur d'un element de la matrice resultat,les valeurs des elements des matrices ayant servi dans les operations....
    Exemple d'operations de produits matriciels generes par des transforms successives illustrant la difficulte du probleme(valeurs resultats M11,M12,M12,M22 sont entre crochets):
    S denote un scale,R(theta) une rotation,Sk(tanX,tanY) un skew

    1/S(sx,sx)*R(θ) = [sx*cosθ,sx*sinθ,-sx*sinθ,sx*cosθ]

    2/S(sx,sx)*Sk(tanX,tanY) = [0,sx*tanθX,sx*tanθY,0]

    3/S(sx,sx)*R(θ) *Sk(tanX,tanY)= [sx*sinθ*tanθY,sx*cosθ*tanθY,sx*cosθ*tanθX,-sx*sinθ*tanθX]

    Ensuite au vu de ton besoin (qui n'est pas tres precis à mon avis) :
    1/dans le post sur la rotation de l'adorner c'est "faire pivoter" l'Adorner dans la passe de .....Disposition(pas de Rendu) .

    2/dans ce post c'est filtrer des "transformations indesirables" sur l'Adorner...... mais pas l'AdornedElement dans la passe de .....Disposition.

    Le 1er exemple repond au souci du 1/ et illustre comment le general "zapata"( GeneralTransformGroup) peut ajouter des transforms supplementaires au LayoutTransform de l'Adorner (scale,rotation)...

    code behind.cs du CustAdornerA(simple Rectangle en TopLeft de l'AdorneElement):
    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
     
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows.Documents;
    using System.Windows.Controls;
    using System.Windows;
    using System.Windows.Media;
    using System.Windows.Shapes;
    using System.Windows.Input;
     
    namespace WpfUserControlAdorner
    {
        public class CustAdornerA : Adorner
        {
            private Rectangle _presenter;
            // To store and manage the adorner's visual children.
            VisualCollection visualChildren;
     
            public CustAdornerA(UIElement adornedElt)
                : base(adornedElt)
            {
                visualChildren = new VisualCollection(this);
                AddVisual();
     
     
            }
            protected override Size MeasureOverride(Size constraint)
            {
                _presenter.Measure(constraint);
                return constraint;
            }
     
            protected override Size ArrangeOverride(Size finalSize)
            {
                double desiredWidth = AdornedElement.DesiredSize.Width;
                double desiredHeight = AdornedElement.DesiredSize.Height;
     
                // adornerWidth & adornerHeight are used for placement as well.
                double adornerWidth = this.DesiredSize.Width;
                double adornerHeight = this.DesiredSize.Height;
     
                //arrange _presenter
                Rect  rect = new Rect(-adornerWidth / 2, -adornerHeight / 2, adornerWidth, adornerHeight);
                _presenter.Arrange(rect);
                return finalSize;
            }
            // Override the VisualChildrenCount and GetVisualChild properties to interface with 
            // the adorner's visual collection.
            protected override int VisualChildrenCount { get { return visualChildren.Count; } }
            protected override Visual GetVisualChild(int index) { return visualChildren[index]; }
     
            //  Add the Visual to  adorner's visual collection.
            private void AddVisual()
            {
                _presenter = new Rectangle ();
                _presenter.Stroke = Brushes.Black;
                _presenter.Fill= Brushes.LightBlue;
                _presenter.Width = 10;
                _presenter.Height = 10; 
                _presenter.IsHitTestVisible = true;
                 visualChildren.Add(_presenter);
            }
     
            // Appele avant passe LayoutTransform(Disposition)
            // par le layer..en sous-main
            public override GeneralTransform GetDesiredTransform(GeneralTransform transform)
            {
                // Rajout d'un GeneralTransformGroup aux transforms originales
                // renvoi  tout à layer
     
                GeneralTransformGroup result = new GeneralTransformGroup();
                //multiplie size de l'adorner par 2.0
                result.Children.Add(new ScaleTransform(2.0, 2.0));
                //pivote de 30.0 degres l'adorner
                result.Children.Add( new RotateTransform(30.0,0,0));
                result.Children.Add(new SkewTransform(0.0, 0.0));
                result.Children.Add(base.GetDesiredTransform(transform));
     
                return result;
            }
     
        }
    }
    code xaml du winform d'utilisation:
    [code]
    <Window x:Class="WpfUserControlAdorner.WinCustAdornerA"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="CustAdornerA" Height="300" Width="300"
    Loaded="Window_Loaded">
    <DockPanel >
    <Slider
    Name="sliderScale"
    Orientation="Vertical"
    DockPanel.Dock="Left"
    Minimum="0.25"
    Maximum="1.75"
    Value="1">
    </Slider>
    <Separator
    DockPanel.Dock="Left"
    HorizontalAlignment="Center"
    Width="10"/>
    <Slider
    Name="sliderRotation"
    Orientation="Vertical"
    DockPanel.Dock="Left"
    Minimum="-180"
    Maximum="180"
    Value="0">
    </Slider>
    <Slider
    Orientation="Vertical"
    DockPanel.Dock="Right"
    Name="sliderSkew"
    Minimum="-180"
    Maximum="180"
    Value="0">
    </Slider>
    <ScrollViewer
    ScrollViewer.HorizontalScrollBarVisibility="Auto"
    ScrollViewer.VerticalScrollBarVisibility="Auto"
    VerticalContentAlignment="Top"
    HorizontalContentAlignment="Left">
    <Border
    DockPanel.Dock="Left"
    x:Name="elementBase"
    Background="Transparent"
    Width="450"
    Height="400"
    HorizontalAlignment="Stretch"
    VerticalAlignment="Stretch"
    BorderBrush="DarkBlue"
    BorderThickness="1">
    <Border.LayoutTransform>
    <TransformGroup x:Name="myTransformGroup">
    <ScaleTransform
    ScaleX="{Binding Value, ElementName=sliderScale}"
    ScaleY="{Binding Value, ElementName=sliderScale}" />
    <SkewTransform
    CenterX="0.5"
    CenterY="0.5"
    AngleX="{Binding Value, ElementName=sliderSkew}"
    AngleY="{Binding Value, ElementName=sliderSkew}">
    </SkewTransform>
    <RotateTransform
    CenterX="0.5"
    CenterY="0.5"
    Angle="{Binding Value, ElementName=sliderRotation}" >
    </RotateTransform>
    <TranslateTransform />
    </TransformGroup>
    </Border.LayoutTransform>
    <Canvas
    x:Name="MyCanvas"
    Background="White"
    ClipToBounds="True">
    <Ellipse
    Canvas.Left="100"
    Canvas.Top="100"
    Width="100"
    Height="50"
    Fill="Aquamarine">
    </Ellipse>
    <Button
    Canvas.Left="150"
    Canvas.Top="200"
    Width="100"
    Content="MyButton">
    </Button >
    </Canvas>
    </Border>
    </ScrollViewer>
    </DockPanel>
    </Window>
    [CODE]
    code .cs du winform:
    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
     
    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 WpfUserControlAdorner
    {
        /// <summary>
        /// Logique d'interaction pour WinCustAdornerA.xaml
        /// </summary>
        public partial class WinCustAdornerA : Window
        {
            AdornerLayer layer;
            CustAdornerA adorner;
            public WinCustAdornerA()
            {
                InitializeComponent();
            }
     
            private void Window_Loaded(object sender, RoutedEventArgs e)
            {
                layer = AdornerLayer.GetAdornerLayer(this.MyCanvas);
                foreach (FrameworkElement elem in this.MyCanvas.Children)
                {
                    adorner = new CustAdornerA(elem);
                    layer.Add(adorner);
                }
            }
        }
    }
    Le 2e exemple repond au souci du 2/ et utilise le fait -oublie par toi-que l'on peut passer en parametre le TransformGroup de ton LayoutTrnsform à l'Adorner .
    Ensuite on extrait chaque transform ,on l'inverse et on "refile" au layer en lieu et place un autre GeneralTransform modifie...

    code behind .cs du CustAdornerB :
    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
     
     
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows.Documents;
    using System.Windows.Controls;
    using System.Windows;
    using System.Windows.Media;
    using System.Windows.Shapes;
    using System.Windows.Input;
     
    namespace WpfUserControlAdorner
    {
        public class CustAdornerB : Adorner
        {
     
            private Rectangle _presenter;
            // To store and manage the adorner's visual children.
            VisualCollection visualChildren;
     
            //Filtre GeneralTransformGroup
            private GeneralTransformGroup resultFilter;
     
            //parametre TransformGroup de la passe courante LayoutTransform ou Disposition
            //agit sur MeasureOverride =>DesiredSize et sur ArrangeOverride=>rect
     
            private TransformGroup myTrfGroup;
     
            // nos transforms courantes seront modifies
            // pour agir sur passe courante LayoutTransform(disposition)
            private ScaleTransform myScale;
            private RotateTransform myRotation;
            private SkewTransform mySkew;
            public CustAdornerB(UIElement adornedElt,TransformGroup trfGroup)
                : base(adornedElt)
            {
                myTrfGroup = trfGroup;
                visualChildren = new VisualCollection(this);
                AddVisual();
     
     
            }
            protected override Size MeasureOverride(Size constraint)
            {
                _presenter.Measure(constraint);
                return constraint;
            }
     
            protected override Size ArrangeOverride(Size finalSize)
            {
                double desiredWidth = AdornedElement.DesiredSize.Width;
                double desiredHeight = AdornedElement.DesiredSize.Height;
     
                // adornerWidth & adornerHeight are used for placement as well.
                double adornerWidth = this.DesiredSize.Width;
                double adornerHeight = this.DesiredSize.Height;
     
                //arrange _presenter
                Rect  rect = new Rect(-adornerWidth / 2, -adornerHeight / 2, adornerWidth, adornerHeight);
                _presenter.Arrange(rect);
     
                return finalSize;
            }
            // Override the VisualChildrenCount and GetVisualChild properties to interface with 
            // the adorner's visual collection.
            protected override int VisualChildrenCount { get { return visualChildren.Count; } }
            protected override Visual GetVisualChild(int index) { return visualChildren[index]; }
     
            //  Add the Visual to  adorner's visual collection.
            private void AddVisual()
            {
                _presenter = new Rectangle ();
                _presenter.Stroke = Brushes.Black;
                _presenter.Fill= Brushes.LightBlue;
                _presenter.Width = 10;
                _presenter.Height = 10; 
                _presenter.IsHitTestVisible = true;
                visualChildren.Add(_presenter);
            }
            //Appele avant passe LayoutTransform(Disposition)
            // par le layer..en sous-main
            public override GeneralTransform GetDesiredTransform(GeneralTransform transform)
            {
                // Recupere nos transforms courantes apres modifications
                // renvoi tout ( en lieu et place des originales) à layer
     
                ModifiedTransforms(myTrfGroup);
                resultFilter.Children.Add(base.GetDesiredTransform(transform));
     
                return resultFilter;
            }
            //Modifie nos transforms courantes 
            private void ModifiedTransforms(TransformGroup currentGroupe)
            {
                resultFilter = new GeneralTransformGroup();
                for (int i = 0; i < currentGroupe.Children.Count; i++)
                {
                    Transform trf = currentGroupe.Children[i];
                    if (trf.GetType() == typeof(ScaleTransform))
                    {
                        myScale = (ScaleTransform)currentGroupe.Children[i];
                        double x = myScale.ScaleX;
                        double y = myScale.ScaleY;
                        resultFilter.Children.Add(new ScaleTransform(1 / x, 1 / y));
                    }
                    else if (trf.GetType() == typeof(RotateTransform))
                    {
                        myRotation = (RotateTransform)currentGroupe.Children[i];
                        double theta = myRotation.Angle;
                        resultFilter.Children.Add(new RotateTransform(-theta, 0.5, 0.5));
                    }
                    else if (trf.GetType() == typeof(SkewTransform))
                    {
                        mySkew = (SkewTransform)currentGroupe.Children[i];
                        double thetaX = mySkew.AngleX;
                        double thetaY = mySkew.AngleY;
                        resultFilter.Children.Add(new SkewTransform(-thetaX, -thetaY));
     
                    }
                }
     
            }
     
     
     
        }
    }
    code du winform utilisateur:
    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
     
     
    <Window x:Class="WpfUserControlAdorner.WinCustAdornerB"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="CustAdornerB" Height="300" Width="300"
            Loaded="Window_Loaded">
        <DockPanel >
            <Slider
                Name="sliderScale"  
                Orientation="Vertical"
                DockPanel.Dock="Left"
                Minimum="0.25"
                Maximum="1.75"
                Value="1">
            </Slider>
            <Separator 
                DockPanel.Dock="Left"
                HorizontalAlignment="Center"
                Width="10"/>
            <Slider
                Name="sliderRotation" 
                Orientation="Vertical"
                DockPanel.Dock="Left"
                Minimum="-180"
                Maximum="180"
                Value="0">
            </Slider>
            <Slider
                Orientation="Vertical"
                DockPanel.Dock="Right"
                Name="sliderSkew" 
                Minimum="-180"
                Maximum="180"
                Value="0">
            </Slider>
            <ScrollViewer
                ScrollViewer.HorizontalScrollBarVisibility="Auto"
                ScrollViewer.VerticalScrollBarVisibility="Auto"
                VerticalContentAlignment="Top"
                HorizontalContentAlignment="Left">
                <Border 
                    DockPanel.Dock="Left"
                    x:Name="elementBase"
                    Background="Transparent"
                    Width="450"
                    Height="400"
                    HorizontalAlignment="Stretch"
                    VerticalAlignment="Stretch"
                    BorderBrush="DarkBlue"
                    BorderThickness="1">
                    <Border.LayoutTransform>
                        <TransformGroup x:Name="myTransformGroup">
                            <ScaleTransform
                                        ScaleX="{Binding Value, ElementName=sliderScale}"
                                        ScaleY="{Binding Value, ElementName=sliderScale}" />
                            <SkewTransform
                                         CenterX="0.5"
                                         CenterY="0.5"
                                         AngleX="{Binding Value, ElementName=sliderSkew}"
                                         AngleY="{Binding Value, ElementName=sliderSkew}">
                            </SkewTransform>
                            <RotateTransform 
                                        CenterX="0.5"
                                        CenterY="0.5"
                                        Angle="{Binding Value, ElementName=sliderRotation}" >
                            </RotateTransform>
                            <TranslateTransform />
                        </TransformGroup>
                    </Border.LayoutTransform>
                    <Canvas
                            x:Name="MyCanvas"
                            Background="White"
                            ClipToBounds="True">
                        <Ellipse
                            Canvas.Left="100"
                            Canvas.Top="100"
                            Width="100"
                            Height="50"
                            Fill="Aquamarine">
                        </Ellipse>
                        <Button 
                            Canvas.Left="150"
                            Canvas.Top="200"
                            Width="100"
                            Content="MyButton">
                        </Button >
                    </Canvas>
                </Border>
            </ScrollViewer>
        </DockPanel>
    </Window>
    code .cs du winform:
    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
     
     
    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 WpfUserControlAdorner
    {
        /// <summary>
        /// Logique d'interaction pour WinCustAdornerB.xaml
        /// </summary>
        public partial class WinCustAdornerB : Window
        {
            AdornerLayer layer;
            CustAdornerB adorner;
            public WinCustAdornerB()
            {
                InitializeComponent();
            }
     
            private void Window_Loaded(object sender, RoutedEventArgs e)
            {
                layer = AdornerLayer.GetAdornerLayer(this.MyCanvas);
                foreach (FrameworkElement elem in this.MyCanvas.Children)
                {
                    adorner = new CustAdornerB(elem,this.myTransformGroup);
                    layer.Add(adorner);
                }
            }
        }
    }
    Evidement l'Adorner peut etre -au lieu d'un simple rectangle- carrement un UserControl qui expose "4 corners" Rectangle en DependencyProperty et la modif de transform sera appliquee uniqument aux "4 corners" Rectangle...
    Il n'est pas necessaire d'ecrirce du code en plus dans measureoverride ou arrangeoverride ....
    bon code.............

  3. #3
    Expert confirmé
    Inscrit en
    Avril 2008
    Messages
    2 564
    Détails du profil
    Informations personnelles :
    Âge : 64

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 564
    Points : 4 441
    Points
    4 441
    Par défaut
    bonjour ikeas....
    Vu la definition meme des operations matricielles(mul,add) on ne peut determiner à partir de la valeur d'un element de la matrice resultat,les valeurs des elements des matrices ayant servi dans les operations....
    Exemple d'operations de produits matriciels generes par des transforms successives illustrant la difficulte du probleme(valeurs resultats M11,M12,M12,M22 sont entre crochets):
    S denote un scale,R(theta) une rotation,Sk(tanX,tanY) un skew

    1/S(sx,sx)*R(θ) = [sx*cosθ,sx*sinθ,-sx*sinθ,sx*cosθ]

    2/S(sx,sx)*Sk(tanX,tanY) = [0,sx*tanθX,sx*tanθY,0]

    3/S(sx,sx)*R(θ) *Sk(tanX,tanY)= [sx*sinθ*tanθY,sx*cosθ*tanθY,sx*cosθ*tanθX,-sx*sinθ*tanθX]

    Ensuite au vu de ton besoin (qui n'est pas tres precis à mon avis) :
    1/dans le post sur la rotation de l'adorner c'est "faire pivoter" l'Adorner dans la passe de .....Disposition(pas de Rendu) .

    2/dans ce post c'est filtrer des "transformations indesirables" sur l'Adorner...... mais pas l'AdornedElement dans la passe de .....Disposition.

    Le 1er exemple repond au souci du 1/ et illustre comment le general "zapata"( GeneralTransformGroup) peut ajouter des transforms supplementaires au LayoutTransform de l'Adorner (scale,rotation)...

    code behind.cs du CustAdornerA(simple Rectangle en TopLeft de l'AdorneElement):
    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
     
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows.Documents;
    using System.Windows.Controls;
    using System.Windows;
    using System.Windows.Media;
    using System.Windows.Shapes;
    using System.Windows.Input;
     
    namespace WpfUserControlAdorner
    {
        public class CustAdornerA : Adorner
        {
            private Rectangle _presenter;
            // To store and manage the adorner's visual children.
            VisualCollection visualChildren;
     
            public CustAdornerA(UIElement adornedElt)
                : base(adornedElt)
            {
                visualChildren = new VisualCollection(this);
                AddVisual();
     
     
            }
            protected override Size MeasureOverride(Size constraint)
            {
                _presenter.Measure(constraint);
                return constraint;
            }
     
            protected override Size ArrangeOverride(Size finalSize)
            {
                double desiredWidth = AdornedElement.DesiredSize.Width;
                double desiredHeight = AdornedElement.DesiredSize.Height;
     
                // adornerWidth & adornerHeight are used for placement as well.
                double adornerWidth = this.DesiredSize.Width;
                double adornerHeight = this.DesiredSize.Height;
     
                //arrange _presenter
                Rect  rect = new Rect(-adornerWidth / 2, -adornerHeight / 2, adornerWidth, adornerHeight);
                _presenter.Arrange(rect);
                return finalSize;
            }
            // Override the VisualChildrenCount and GetVisualChild properties to interface with 
            // the adorner's visual collection.
            protected override int VisualChildrenCount { get { return visualChildren.Count; } }
            protected override Visual GetVisualChild(int index) { return visualChildren[index]; }
     
            //  Add the Visual to  adorner's visual collection.
            private void AddVisual()
            {
                _presenter = new Rectangle ();
                _presenter.Stroke = Brushes.Black;
                _presenter.Fill= Brushes.LightBlue;
                _presenter.Width = 10;
                _presenter.Height = 10; 
                _presenter.IsHitTestVisible = true;
                 visualChildren.Add(_presenter);
            }
     
            // Appele avant passe LayoutTransform(Disposition)
            // par le layer..en sous-main
            public override GeneralTransform GetDesiredTransform(GeneralTransform transform)
            {
                // Rajout d'un GeneralTransformGroup aux transforms originales
                // renvoi  tout à layer
     
                GeneralTransformGroup result = new GeneralTransformGroup();
                //multiplie size de l'adorner par 2.0
                result.Children.Add(new ScaleTransform(2.0, 2.0));
                //pivote de 30.0 degres l'adorner
                result.Children.Add( new RotateTransform(30.0,0,0));
                result.Children.Add(new SkewTransform(0.0, 0.0));
                result.Children.Add(base.GetDesiredTransform(transform));
     
                return result;
            }
     
        }
    }
    code xaml du winform d'utilisation:
    [code]
    <Window x:Class="WpfUserControlAdorner.WinCustAdornerA"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="CustAdornerA" Height="300" Width="300"
    Loaded="Window_Loaded">
    <DockPanel >
    <Slider
    Name="sliderScale"
    Orientation="Vertical"
    DockPanel.Dock="Left"
    Minimum="0.25"
    Maximum="1.75"
    Value="1">
    </Slider>
    <Separator
    DockPanel.Dock="Left"
    HorizontalAlignment="Center"
    Width="10"/>
    <Slider
    Name="sliderRotation"
    Orientation="Vertical"
    DockPanel.Dock="Left"
    Minimum="-180"
    Maximum="180"
    Value="0">
    </Slider>
    <Slider
    Orientation="Vertical"
    DockPanel.Dock="Right"
    Name="sliderSkew"
    Minimum="-180"
    Maximum="180"
    Value="0">
    </Slider>
    <ScrollViewer
    ScrollViewer.HorizontalScrollBarVisibility="Auto"
    ScrollViewer.VerticalScrollBarVisibility="Auto"
    VerticalContentAlignment="Top"
    HorizontalContentAlignment="Left">
    <Border
    DockPanel.Dock="Left"
    x:Name="elementBase"
    Background="Transparent"
    Width="450"
    Height="400"
    HorizontalAlignment="Stretch"
    VerticalAlignment="Stretch"
    BorderBrush="DarkBlue"
    BorderThickness="1">
    <Border.LayoutTransform>
    <TransformGroup x:Name="myTransformGroup">
    <ScaleTransform
    ScaleX="{Binding Value, ElementName=sliderScale}"
    ScaleY="{Binding Value, ElementName=sliderScale}" />
    <SkewTransform
    CenterX="0.5"
    CenterY="0.5"
    AngleX="{Binding Value, ElementName=sliderSkew}"
    AngleY="{Binding Value, ElementName=sliderSkew}">
    </SkewTransform>
    <RotateTransform
    CenterX="0.5"
    CenterY="0.5"
    Angle="{Binding Value, ElementName=sliderRotation}" >
    </RotateTransform>
    <TranslateTransform />
    </TransformGroup>
    </Border.LayoutTransform>
    <Canvas
    x:Name="MyCanvas"
    Background="White"
    ClipToBounds="True">
    <Ellipse
    Canvas.Left="100"
    Canvas.Top="100"
    Width="100"
    Height="50"
    Fill="Aquamarine">
    </Ellipse>
    <Button
    Canvas.Left="150"
    Canvas.Top="200"
    Width="100"
    Content="MyButton">
    </Button >
    </Canvas>
    </Border>
    </ScrollViewer>
    </DockPanel>
    </Window>
    [CODE]
    code .cs du winform:
    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
     
    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 WpfUserControlAdorner
    {
        /// <summary>
        /// Logique d'interaction pour WinCustAdornerA.xaml
        /// </summary>
        public partial class WinCustAdornerA : Window
        {
            AdornerLayer layer;
            CustAdornerA adorner;
            public WinCustAdornerA()
            {
                InitializeComponent();
            }
     
            private void Window_Loaded(object sender, RoutedEventArgs e)
            {
                layer = AdornerLayer.GetAdornerLayer(this.MyCanvas);
                foreach (FrameworkElement elem in this.MyCanvas.Children)
                {
                    adorner = new CustAdornerA(elem);
                    layer.Add(adorner);
                }
            }
        }
    }
    Le 2e exemple repond au souci du 2/ et utilise le fait -oublie par toi-que l'on peut passer en parametre le TransformGroup de ton LayoutTrnsform à l'Adorner .
    Ensuite on extrait chaque transform ,on l'inverse et on "refile" au layer en lieu et place un autre GeneralTransform modifie...

    code behind .cs du CustAdornerB :
    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
     
     
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows.Documents;
    using System.Windows.Controls;
    using System.Windows;
    using System.Windows.Media;
    using System.Windows.Shapes;
    using System.Windows.Input;
     
    namespace WpfUserControlAdorner
    {
        public class CustAdornerB : Adorner
        {
     
            private Rectangle _presenter;
            // To store and manage the adorner's visual children.
            VisualCollection visualChildren;
     
            //Filtre GeneralTransformGroup
            private GeneralTransformGroup resultFilter;
     
            //parametre TransformGroup de la passe courante LayoutTransform ou Disposition
            //agit sur MeasureOverride =>DesiredSize et sur ArrangeOverride=>rect
     
            private TransformGroup myTrfGroup;
     
            // nos transforms courantes seront modifies
            // pour agir sur passe courante LayoutTransform(disposition)
            private ScaleTransform myScale;
            private RotateTransform myRotation;
            private SkewTransform mySkew;
            public CustAdornerB(UIElement adornedElt,TransformGroup trfGroup)
                : base(adornedElt)
            {
                myTrfGroup = trfGroup;
                visualChildren = new VisualCollection(this);
                AddVisual();
     
     
            }
            protected override Size MeasureOverride(Size constraint)
            {
                _presenter.Measure(constraint);
                return constraint;
            }
     
            protected override Size ArrangeOverride(Size finalSize)
            {
                double desiredWidth = AdornedElement.DesiredSize.Width;
                double desiredHeight = AdornedElement.DesiredSize.Height;
     
                // adornerWidth & adornerHeight are used for placement as well.
                double adornerWidth = this.DesiredSize.Width;
                double adornerHeight = this.DesiredSize.Height;
     
                //arrange _presenter
                Rect  rect = new Rect(-adornerWidth / 2, -adornerHeight / 2, adornerWidth, adornerHeight);
                _presenter.Arrange(rect);
     
                return finalSize;
            }
            // Override the VisualChildrenCount and GetVisualChild properties to interface with 
            // the adorner's visual collection.
            protected override int VisualChildrenCount { get { return visualChildren.Count; } }
            protected override Visual GetVisualChild(int index) { return visualChildren[index]; }
     
            //  Add the Visual to  adorner's visual collection.
            private void AddVisual()
            {
                _presenter = new Rectangle ();
                _presenter.Stroke = Brushes.Black;
                _presenter.Fill= Brushes.LightBlue;
                _presenter.Width = 10;
                _presenter.Height = 10; 
                _presenter.IsHitTestVisible = true;
                visualChildren.Add(_presenter);
            }
            //Appele avant passe LayoutTransform(Disposition)
            // par le layer..en sous-main
            public override GeneralTransform GetDesiredTransform(GeneralTransform transform)
            {
                // Recupere nos transforms courantes apres modifications
                // renvoi tout ( en lieu et place des originales) à layer
     
                ModifiedTransforms(myTrfGroup);
                resultFilter.Children.Add(base.GetDesiredTransform(transform));
     
                return resultFilter;
            }
            //Modifie nos transforms courantes 
            private void ModifiedTransforms(TransformGroup currentGroupe)
            {
                resultFilter = new GeneralTransformGroup();
                for (int i = 0; i < currentGroupe.Children.Count; i++)
                {
                    Transform trf = currentGroupe.Children[i];
                    if (trf.GetType() == typeof(ScaleTransform))
                    {
                        myScale = (ScaleTransform)currentGroupe.Children[i];
                        double x = myScale.ScaleX;
                        double y = myScale.ScaleY;
                        resultFilter.Children.Add(new ScaleTransform(1 / x, 1 / y));
                    }
                    else if (trf.GetType() == typeof(RotateTransform))
                    {
                        myRotation = (RotateTransform)currentGroupe.Children[i];
                        double theta = myRotation.Angle;
                        resultFilter.Children.Add(new RotateTransform(-theta, 0.5, 0.5));
                    }
                    else if (trf.GetType() == typeof(SkewTransform))
                    {
                        mySkew = (SkewTransform)currentGroupe.Children[i];
                        double thetaX = mySkew.AngleX;
                        double thetaY = mySkew.AngleY;
                        resultFilter.Children.Add(new SkewTransform(-thetaX, -thetaY));
     
                    }
                }
     
            }
     
     
     
        }
    }
    code du winform utilisateur:
    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
     
     
    <Window x:Class="WpfUserControlAdorner.WinCustAdornerB"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="CustAdornerB" Height="300" Width="300"
            Loaded="Window_Loaded">
        <DockPanel >
            <Slider
                Name="sliderScale"  
                Orientation="Vertical"
                DockPanel.Dock="Left"
                Minimum="0.25"
                Maximum="1.75"
                Value="1">
            </Slider>
            <Separator 
                DockPanel.Dock="Left"
                HorizontalAlignment="Center"
                Width="10"/>
            <Slider
                Name="sliderRotation" 
                Orientation="Vertical"
                DockPanel.Dock="Left"
                Minimum="-180"
                Maximum="180"
                Value="0">
            </Slider>
            <Slider
                Orientation="Vertical"
                DockPanel.Dock="Right"
                Name="sliderSkew" 
                Minimum="-180"
                Maximum="180"
                Value="0">
            </Slider>
            <ScrollViewer
                ScrollViewer.HorizontalScrollBarVisibility="Auto"
                ScrollViewer.VerticalScrollBarVisibility="Auto"
                VerticalContentAlignment="Top"
                HorizontalContentAlignment="Left">
                <Border 
                    DockPanel.Dock="Left"
                    x:Name="elementBase"
                    Background="Transparent"
                    Width="450"
                    Height="400"
                    HorizontalAlignment="Stretch"
                    VerticalAlignment="Stretch"
                    BorderBrush="DarkBlue"
                    BorderThickness="1">
                    <Border.LayoutTransform>
                        <TransformGroup x:Name="myTransformGroup">
                            <ScaleTransform
                                        ScaleX="{Binding Value, ElementName=sliderScale}"
                                        ScaleY="{Binding Value, ElementName=sliderScale}" />
                            <SkewTransform
                                         CenterX="0.5"
                                         CenterY="0.5"
                                         AngleX="{Binding Value, ElementName=sliderSkew}"
                                         AngleY="{Binding Value, ElementName=sliderSkew}">
                            </SkewTransform>
                            <RotateTransform 
                                        CenterX="0.5"
                                        CenterY="0.5"
                                        Angle="{Binding Value, ElementName=sliderRotation}" >
                            </RotateTransform>
                            <TranslateTransform />
                        </TransformGroup>
                    </Border.LayoutTransform>
                    <Canvas
                            x:Name="MyCanvas"
                            Background="White"
                            ClipToBounds="True">
                        <Ellipse
                            Canvas.Left="100"
                            Canvas.Top="100"
                            Width="100"
                            Height="50"
                            Fill="Aquamarine">
                        </Ellipse>
                        <Button 
                            Canvas.Left="150"
                            Canvas.Top="200"
                            Width="100"
                            Content="MyButton">
                        </Button >
                    </Canvas>
                </Border>
            </ScrollViewer>
        </DockPanel>
    </Window>
    code .cs du winform:
    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
     
     
    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 WpfUserControlAdorner
    {
        /// <summary>
        /// Logique d'interaction pour WinCustAdornerB.xaml
        /// </summary>
        public partial class WinCustAdornerB : Window
        {
            AdornerLayer layer;
            CustAdornerB adorner;
            public WinCustAdornerB()
            {
                InitializeComponent();
            }
     
            private void Window_Loaded(object sender, RoutedEventArgs e)
            {
                layer = AdornerLayer.GetAdornerLayer(this.MyCanvas);
                foreach (FrameworkElement elem in this.MyCanvas.Children)
                {
                    adorner = new CustAdornerB(elem,this.myTransformGroup);
                    layer.Add(adorner);
                }
            }
        }
    }
    Evidement l'Adorner peut etre -au lieu d'un simple rectangle- carrement un UserControl qui expose "4 corners" Rectangle en DependencyProperty et la modif de transform sera appliquee uniqument aux "4 corners" Rectangle...
    Il n'est pas necessaire d'ecrirce du code en plus dans measureoverride ou arrangeoverride ....
    bon code.............

  4. #4
    Membre expérimenté
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 562
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 562
    Points : 1 313
    Points
    1 313
    Par défaut
    en fait j'ai trouvé bcp plus simple pour evaluer les bounds d'un objet en rotation

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    private Rect GetBounds(FrameworkElement of, FrameworkElement from)
            {
                // Might throw an exception if of and from are not in the same visual tree
                GeneralTransform transform = of.TransformToVisual(from);
     
                return transform.TransformBounds(new Rect(0, 0, of.ActualWidth, of.ActualHeight));
            }
    en utilisant les transformations

    mais merci quand meme
    IKEAS : Finalement je crois que c'est dans ses faiblesses que l'on y trouve a la fois de la force et a la fois de la richesse...
    ----------------------------------------------------
    Si vous avez du taf en wpf & design d'application sympa, contactez moi !!!!
    http://ultimatecorp.eu/wpf/

Discussions similaires

  1. Portsentry, comment lui faire envoyer un mail ?
    Par baali_hacene dans le forum Réseau
    Réponses: 3
    Dernier message: 19/04/2006, 19h06
  2. [Generation BDD]Comment le faire à partir d'un fichier .BAK?
    Par silvain dans le forum MS SQL Server
    Réponses: 1
    Dernier message: 01/02/2006, 16h10
  3. [ant] comment le faire marcher?
    Par afrikha dans le forum ANT
    Réponses: 11
    Dernier message: 23/12/2005, 16h18
  4. ClassWizard --> comment lui faire reconnaitre mes classes
    Par bigboomshakala dans le forum MFC
    Réponses: 6
    Dernier message: 06/05/2004, 10h50

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