+ Répondre à la discussion
Affichage des résultats 1 à 4 sur 4
  1. #1
    Membre Expert
    Inscrit en
    juillet 2008
    Messages
    1 224
    Détails du profil
    Informations forums :
    Inscription : juillet 2008
    Messages : 1 224
    Points : 1 073
    Points
    1 073

    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 !!!!

  2. #2
    Membre Expert
    Inscrit en
    avril 2008
    Messages
    1 337
    Détails du profil
    Informations personnelles :
    Âge : 55

    Informations forums :
    Inscription : avril 2008
    Messages : 1 337
    Points : 2 240
    Points
    2 240

    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 :
    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 :
    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 :
    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 :
    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 :
    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
    Membre Expert
    Inscrit en
    avril 2008
    Messages
    1 337
    Détails du profil
    Informations personnelles :
    Âge : 55

    Informations forums :
    Inscription : avril 2008
    Messages : 1 337
    Points : 2 240
    Points
    2 240

    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 :
    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 :
    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 :
    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 :
    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 :
    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 Expert
    Inscrit en
    juillet 2008
    Messages
    1 224
    Détails du profil
    Informations forums :
    Inscription : juillet 2008
    Messages : 1 224
    Points : 1 073
    Points
    1 073

    Par défaut

    en fait j'ai trouvé bcp plus simple pour evaluer les bounds d'un objet en rotation

    Code :
    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 !!!!

Liens sociaux

Règles de messages

  • Vous ne pouvez pas créer de nouvelles discussions
  • Vous ne pouvez pas envoyer des réponses
  • Vous ne pouvez pas envoyer des pièces jointes
  • Vous ne pouvez pas modifier vos messages
  •