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 :

Liaison de données dans une animation


Sujet :

Windows Presentation Foundation

  1. #1
    Membre régulier
    Inscrit en
    Juin 2004
    Messages
    69
    Détails du profil
    Informations forums :
    Inscription : Juin 2004
    Messages : 69
    Points : 86
    Points
    86
    Par défaut Liaison de données dans une animation
    Bonjour,

    Programmeur expérimenté en framework .Net 2 (VB et C#), j'ai (enfin ) l'opportunité de me former sur les dernières versions du framework, en particulier WPF, ce que je fais avec plaisir. Mais j'avoue avoir du mal à saisir certains concepts, dont celui présenté ici. Ce que j'essaie de faire n'a sans doute rien de bien compliqué, mais je ne comprends pas vraiment ce qui me bloque, même après avoir cherché des tutoriaux et exemples sur le Net. Je m'en remets donc à des développeurs plus expérimentés.

    J'essaie de créer un système d'affichage de message d'erreurs dynamiques, réutilisable dans différentes applications, personnalisable, facile à utiliser et respectant la séparation interface / code préconisée en .Net 3 et +. Je m'en sers pour appliquer les concepts vus dans les docs que j'ai lues. J'ai donc essayé de faire un TextBlock auquel j'applique un style pour l'esthétique, mais surtout pour déclencher une apparition et un masquage automatiques et progressifs à l'aide d'une animation. Coté code une instance d'un objet contient une propriété "Error" à laquelle un trigger est lié pour déclencher l'animation d'affichage du TextBlock , puis sa disparition. Une autre propriété liée "Message" contient le texte à afficher. Ça marche très bien (j'ai ajouté un bouton pour déclencher manuellement l'erreur à des fins de tests).

    Voici le code :

    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
    <Window x:Class="Test.WindowPrincipale"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="WindowPrincipale" Height="350" Width="525" WindowStartupLocation="CenterScreen" WindowState="Maximized">
     
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="*" />
                <RowDefinition Height="Auto" />
            </Grid.RowDefinitions>
            <Button Grid.Row="0" Height="100" Width="200" Click="Button_Click">Test</Button>
            <TextBlock Grid.Row="1" Name="BandeauErreur">
                <TextBlock.Style>
                    <Style TargetType="TextBlock">
                    <Setter Property="Background" Value="Red" />
                    <Setter Property="Foreground" Value="White" />
                    <Setter Property="FontFamily" Value="Arial" />
                    <Setter Property="FontSize" Value="32" />
                    <Setter Property="Opacity" Value="0" />
                    <Setter Property="VerticalAlignment" Value="Stretch" />
                    <Setter Property="HorizontalAlignment" Value="Stretch" />
                    <Setter Property="Text" Value="{Binding Path=ErrorMessage}" />
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding Path=Error, Mode=OneWay}" Value="True">
                            <DataTrigger.EnterActions>
                                <BeginStoryboard HandoffBehavior="Compose">
                                    <Storyboard >
                                        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="Opacity" Name="Animation">
                                            <LinearDoubleKeyFrame Value="1" KeyTime="0:0:0.125" />
                                            <LinearDoubleKeyFrame Value="1" KeyTime="0:0:1.625" />
                                            <LinearDoubleKeyFrame Value="0" KeyTime="0:0:2.125" />
                                        </DoubleAnimationUsingKeyFrames>
                                    </Storyboard>
                                </BeginStoryboard>
                            </DataTrigger.EnterActions>
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
              </TextBlock.Style>
            </TextBlock>
        </Grid>
    </Window>
    Par contre j'aimerais aussi pouvoir lier les durées des clefs de l'animation pour pouvoir configurer son déroulement à volonté. Ça ne marche pas, même en tentant de lier KeyTime à une propriété "Time" de mon objet (qui renvoit une chaîne "0:0:5" valide) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    <LinearDoubleKeyFrame Value="0" KeyTime="{Binding Path=Time}" />
    L'exécution déclenche une erreur. Si je supprime cette liaison dans la KeyTime ça marche. Mon animation est dans un style qui est lui-même appliqué au TextBlock. C'est l'accès au DataContext qui me pose problème, je pense. Le style en a hérité mais l'animation qu'il contient apparemment non.

    Merci d'avance pour votre aide (en espérant avoir été clair).

  2. #2
    Invité
    Invité(e)
    Par défaut
    Bonjour,

    Ton problème est intéressant à creuser. J'ai aussi beaucoup cherché de mon côté, et fais beaucoup d'essais. ça ne semble pas grand chose à priori mais quand même je n'ai pas réussi à rendre ce temps configurable.

    D'après les sources que j'ai trouvé à ce sujet, c'est parce que la classe "Storyboard" hérite indirectement de la classe "Freezable" et WPF "fige" le storyboard. Du coup, le databinding n'est pas possible sur les objets inclus dans le storyboard.

    J'ai trouvé ce lien qui en parlait.

    Je continuerai à creuser. Si tu as du nouveau toi aussi n'hésites pas à m'en faire part, cela m'intéresse.

  3. #3
    Membre régulier
    Inscrit en
    Juin 2004
    Messages
    69
    Détails du profil
    Informations forums :
    Inscription : Juin 2004
    Messages : 69
    Points : 86
    Points
    86
    Par défaut
    Merci pour ta réponse. J'ai effectivement aussi lu certaines choses sur les freezables qui semblent en rapport avec mon problème. Je creuse dans cette voie.

  4. #4
    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 442
    Points
    4 442
    Par défaut
    bonjour

    En complement à ce que as dit Ph_Gr le probleme du class StoryBoard qui est "Freezable" :
    - Dans un Style (derive de Dispatcher donc Multi-Thread) ,le Storyboard doit etre partage lui aussi entre Threads utilisant notre Style .
    - Pour cela il doit etre "freeze"(geler)et clone... mais son element KeyTime est binde !!!....

    voici l'exemple du "coeur battant" de MSDN Doc qui montre que ce genre debinding fonctionne mais hors d'un style (ou d'un datatemplate):

    code xaml 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
    41
    42
     
    <Window x:Class="WpfBindingAnimation.WinHeartMSDN"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:PresentationOptions="http://schemas.microsoft.com/winfx/2006/xaml/presentation/options" 
              xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
              mc:Ignorable="PresentationOptions"
            xmlns:local="clr-namespace:WpfBindingAnimation" 
            Title="WinHeartMSDN" Height="300" Width="300">
        <Window.Resources>
            <local:DoubleStringConverter x:Key="StringConveter"/>
            <Storyboard x:Key="OnLoaded1" RepeatBehavior="Forever"
                     >
                <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:01" Storyboard.TargetName="PathHeart" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.Y)">
                    <SplineDoubleKeyFrame KeyTime="{Binding Path=UpHeartRate, Converter={StaticResource StringConveter}}" Value="-20"/>
                    <SplineDoubleKeyFrame KeyTime="{Binding Path=DownHeartRate, Converter={StaticResource StringConveter}}" Value="0"/>
                </DoubleAnimationUsingKeyFrames>
            </Storyboard>
        </Window.Resources>
     
     
        <Grid x:Name="LayoutRoot">
            <Path x:Name="PathHeart" 
                  Stretch="Fill" Fill="#FFFF0000" 
                  Data="F1 M 101.833,143C 112.5,132.667 123.167,122.333 132.167,110.556C 141.167,98.7778 148.5,85.5555 153.333,75.8889C 158.167,66.2222 160.5,60.1111 158.667,53.8889C 156.833,47.6667 150.833,41.3333 142.944,38.5C 135.056,35.6667 125.278,36.3333 118.139,39.7222C 111,43.1111 106.5,49.2222 102,55.3333C 97.4995,49.2222 92.9994,43.1111 85.8604,39.7222C 78.7215,36.3333 68.9437,35.6667 61.0548,38.5C 53.1659,41.3333 47.1659,47.6667 45.3326,53.8889C 43.4993,60.1111 45.8326,66.2222 50.6659,75.8889C 55.4993,85.5555 62.8326,98.7778 71.8326,110.556C 80.8326,122.333 91.4993,132.667 102.166,143" RenderTransformOrigin="0.5,0.5" Margin="217.709,157.724,291.709,180">
                <Path.RenderTransform>
                    <TransformGroup>
                        <ScaleTransform ScaleX="1" ScaleY="1"/>
                        <SkewTransform AngleX="0" AngleY="0"/>
                        <RotateTransform Angle="0"/>
                        <TranslateTransform X="0" Y="0"/>
                    </TransformGroup>
                </Path.RenderTransform>
            </Path>
        </Grid>
        <Window.Triggers>
     
            <EventTrigger RoutedEvent="FrameworkElement.Loaded">
                <BeginStoryboard Storyboard="{StaticResource OnLoaded1}"/>
            </EventTrigger>
        </Window.Triggers>
    </Window>
    code behind .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
     
    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 WpfBindingAnimation
    {
        /// <summary>
        /// Logique d'interaction pour WinHeartMSDN.xaml
        /// </summary>
        public partial class WinHeartMSDN : Window
        {
            public WinHeartMSDN()
            {
                InitializeComponent();
                this.DataContext = new MyData(1);
            }
        }
    }
    code behind.cs du class data utilise:

    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
     
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows.Data;
     
    namespace WpfBindingAnimation
    {
     
        public class MyData
        {
     
            private double heartRate;
     
            public double HeartRate
            {
     
                get { return heartRate; }
     
                set { heartRate = value; }
     
            }
     
     
     
            public double UpHeartRate
            {
     
                get { return heartRate / 5; }
     
            }
     
     
     
            public double DownHeartRate
            {
     
                get { return heartRate / 5 * 2; }
     
            }
     
     
     
            public MyData(double heartRate)
            {
     
                this.heartRate = heartRate;
     
            }
     
        }
     
     
     
     
    }
    C'est helas decevant cette histoire du storyboard binde dans un style ou datatemplate ou controltemplate...............

  5. #5
    Invité
    Invité(e)
    Par défaut
    Merci Mabrouki pour ton intervention,

    Quand j'étais allé fouillé dans le "InnerException" lancé au moment de l'initialisation, il y avait l'exception : "Impossible de figer cette arborescence de chronologie Storyboard pour l'utiliser sur les threads."
    Et d'autre part j'étais aussi tombé sur l'exemple que tu nous as montré.
    Cela confirme bien ce que j'avais commencé à trouvé.

    C'est vrai que c'est dommage que l'on ne puisse pas rendre configurable le KeyTime...

  6. #6
    Membre régulier
    Inscrit en
    Juin 2004
    Messages
    69
    Détails du profil
    Informations forums :
    Inscription : Juin 2004
    Messages : 69
    Points : 86
    Points
    86
    Par défaut
    Merci pour vos réponses. Je crois donc avoir obtenu la réponse à ma question. Dommage.

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

Discussions similaires

  1. Liaison des données dans une application multi-couche
    Par Epitt dans le forum Accès aux données
    Réponses: 12
    Dernier message: 09/10/2009, 13h15
  2. Vérification du type de données dans une procédure stockée
    Par biroule dans le forum MS SQL Server
    Réponses: 3
    Dernier message: 16/09/2004, 11h20
  3. Paradox 7 Comment trier et marquer données dans une DBgrid
    Par technico dans le forum Bases de données
    Réponses: 12
    Dernier message: 04/07/2004, 11h08
  4. Données dans une DBgrid
    Par camino dans le forum Bases de données
    Réponses: 4
    Dernier message: 18/02/2004, 03h40
  5. lien hypertexte dans une anim flash
    Par vedder dans le forum Flash
    Réponses: 17
    Dernier message: 14/01/2004, 14h11

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