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 :

[UserControl] trigger event dans Blend


Sujet :

Windows Presentation Foundation

  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Septembre 2013
    Messages
    2
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2013
    Messages : 2
    Points : 2
    Points
    2
    Par défaut [UserControl] trigger event dans Blend
    Bonjour,

    Une question concernant Blend & un UserControl, je vais tenter d'être clair :

    J'ai créé un composant, en C#, je l'utilise dans une fenêtre et j'aurais souhaité assigner une anim (storyboard) lorsqu'on click sur un bouton dans le composant, l'anim n'est pas liée au composant en lui même, elle ne peut être intégrée à celui-ci. Dans mon esprit, ça me paraissait simple/basique mais à priori c'est subtil (ou je loupe qqchose )

    Dans Blend je ne parviens pas à trouver comment assigner un trigger pour effectuer l'opération, j'ai testé plusieurs options:


    1. J'ai créé un event public dans le composant, je l'assigne dans la fenêtre parente
    dans le composant:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
            public event EventHandler Test;
            public void OnTest() {
                EventHandler handler = Test;
                if (null != handler) handler(this, EventArgs.Empty);
            }
    dans la fenetre parent:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    MyComponent.Test+= MyComponent_Test;
    2. Via un button_click, passé en public, d'un bouton du composant

    dans le composant:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
       public void BtnTest_Click(object sender, RoutedEventArgs e) {   }
    dans la fenetre parent:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    MyComponent.btnTest.Click += BtnTest1_Click;
    3. J'ai créé une propriété publique

    dans le composant:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    public bool Mytestl { get { return true; } set { bool test= value; } }

    Je ne retrouve rien dans Blend qui puisse me permettre de créer un trigger au niveau de la fenêtre parente, une idée ?
    Merci d'avance

  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
    j'aurais souhaité assigner une anim (storyboard) lorsqu'on click sur un bouton dans le composant, l'anim n'est pas liée au composant en lui même, elle ne peut être intégrée à celui-ci. Dans mon esprit, ça me paraissait simple/basique mais à priori c'est subtil (ou je loupe qqchose )
    Ton "esprit" erre et vagabonde ...
    Via un bouton (Routed Event) un EventTrigger ne peut démarrer ("trigguéré") que des Storyboards situés dans sa Portée de Nom" (ou NameScope)..
    Et la "portée de nom" est propre à chaque ContentControl(Wonform et UserControl heritent de ContentControl pour rappel)...
    Par suite tu dois renoncer à ton EventTrugger....

    La seule solution à ce problème c'est de le "court-circuiter" via le Binding c.à.d le MVVM...
    Car le Binding transmet ses changements de props et ses commandes par
    dessus la "nuque" des controls...

    Aussi l'astuce est la suivante ;
    1/Ton Form principal :
    - doit servir de DataCintext à tes UserControls
    - doit implémenter INotifyPropertyChanged
    - doit déclarer une prop CLR type bool
    - doit déclarer une instance de RelayCommand (voir exemple ci- après)

    2/dans tes UserControls:
    - il faut utiliser les Styles des divers controls à animer et les DataTriggers qui leur sont associés pour détecter le changement de valeur de la prop CLR mentionnée ci-dessus...
    - la prop Command des divers buttons de démarrage des animations doit etre bindée sur une instance de la prop Command déclarée dans ton Form mentionné précédemment
    code xaml du UserControle siege de l'animation exemple (un label qui "tourne autour d'une ellipse qui sert de path concu dans Blend)

    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
     
     <UserControl x:Class="WpfAnimationBlend.ControlAnimation"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
                 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
                 xmlns:local="clr-namespace:WpfAnimationBlend"
                 mc:Ignorable="d" 
                 d:DesignHeight="300" d:DesignWidth="300" BorderBrush="#FF001EFF">
     
       <Grid >
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition/>
            </Grid.RowDefinitions>
            <!--binding de la prop Command sur RelayCommand-->
            <Button 
                Content="Animate" 
                Command="{Binding Cmd}"
                Background="#FFE61414" 
                BorderBrush="#FF3564C9"
                HorizontalAlignment="Center" 
                VerticalAlignment="Center"/>
            <Canvas 
                Grid.Row="1"
                Height="400" 
                Width="400" 
                >
     
                <Label x:Name="LabelMatrix" 
                       Content="MyLabel" 
                       Background="Blue"
                       Canvas.Left="176" Canvas.Top="29.05" 
                       RenderTransformOrigin="0.5,0.5">
                    <Label.RenderTransform>
                        <TransformGroup>
                            <ScaleTransform/>
                            <SkewTransform/>
                            <RotateTransform/>
                            <TranslateTransform/>
                        </TransformGroup>
                    </Label.RenderTransform>
                    <!--pave à taper--> 
                    <Label.Style>
                        <Style >
                            <Style.Triggers>
                                <!--binding sur prop CLR-->
                                <DataTrigger Binding="{Binding IsReady}" Value="true">
                                    <DataTrigger.EnterActions>
                                        <BeginStoryboard>
                                            <Storyboard >
                                                <DoubleAnimationUsingPath Duration="0:0:2" Source="X" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)" >
                                                    <DoubleAnimationUsingPath.PathGeometry>
                                                        <PathGeometry Figures="M150.735,159.595 C150.735,244.71589 78.205129,313.72 -11.265,313.72 C-100.73513,313.72 -173.265,244.71589 -173.265,159.595 C-173.265,74.474113 -100.73513,5.47 -11.265,5.47 C78.205129,5.47 150.735,74.474113 150.735,159.595 z"/>
                                                    </DoubleAnimationUsingPath.PathGeometry>
                                                </DoubleAnimationUsingPath>
                                                <DoubleAnimationUsingPath Duration="0:0:2" Source="Y" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.Y)">
                                                    <DoubleAnimationUsingPath.PathGeometry>
                                                        <PathGeometry Figures="M150.735,159.595 C150.735,244.71589 78.205129,313.72 -11.265,313.72 C-100.73513,313.72 -173.265,244.71589 -173.265,159.595 C-173.265,74.474113 -100.73513,5.47 -11.265,5.47 C78.205129,5.47 150.735,74.474113 150.735,159.595 z"/>
                                                    </DoubleAnimationUsingPath.PathGeometry>
                                                </DoubleAnimationUsingPath>
                                            </Storyboard>
                                        </BeginStoryboard>
                                    </DataTrigger.EnterActions>
                                </DataTrigger>
                            </Style.Triggers>
                        </Style>
                    </Label.Style>
                </Label>
            </Canvas>
     
        </Grid>
    </UserControl>
    NB:Le pavé Style du Label et ses Triggers sont tapés à la main car Blend ne dispose de cette fonctionnalité..
    Seule l'animation a été recopie du UserControl.Resources...


    code xaml du UserControle "Intru ou importun" (ton control):

    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
     
    <UserControl x:Class="WpfAnimationBlend.ControlImportun"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
                 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
                 xmlns:local="clr-namespace:WpfAnimationBlend"
                 mc:Ignorable="d" 
                 d:DesignHeight="300" d:DesignWidth="300">
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="auto"></RowDefinition>
            </Grid.RowDefinitions>
            <!--binding de la prop Command sur RelayCommand-->
            <Button  
                Content="Animate"
                Command="{Binding Cmd}"
                Background="#FFE61414" 
                BorderBrush="#FF3564C9"
                HorizontalAlignment="Center"
                VerticalAlignment="Center">
            </Button>
        </Grid>
    </UserControl>
    code xaml du Form User servant de Container et de DataContext pour les 2 UsersControls:
    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
     
    <Window x:Class="WpfAnimationBlend.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:local="clr-namespace:WpfAnimationBlend"
            mc:Ignorable="d"
            Title="MainWindow" Height="350" Width="525"
            >
     
     
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="auto"></ColumnDefinition>
                <ColumnDefinition Width="auto"></ColumnDefinition>
            </Grid.ColumnDefinitions>
            <local:ControlAnimation Grid.Column="0"/>
            <local:ControlImportun Grid.Column="1"/>
        </Grid>
    </Window>
    code behind.cs "vital" du form :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
     
    namespace WpfAnimationBlend
    {
        /// <summary>
        /// Logique d'interaction pour MainWindow.xaml
        /// </summary>
        public partial class MainWindow : Window,INotifyPropertyChanged
        {
     
            public MainWindow()
            {
                InitializeComponent();
                this.DataContext = this;// VITAL
                Cmd = new MyCommand(Animate, CanAnimate);
            }
     
     
            //prop CLR
            private bool isReady;
            public bool IsReady
            {
                get { return isReady; }
                set
                {
                    isReady = value;
                    Raise("IsReady");
                }
            }
            public event PropertyChangedEventHandler PropertyChanged;
            private void Raise(string nameProp)
            {
                PropertyChangedEventHandler h = PropertyChanged;
                if (h != null)
                    h(this, new PropertyChangedEventArgs(nameProp));
            }
            // prop command
            public MyCommand Cmd { get; set; }
            private void Animate()
            {
                this.IsReady =!this.isReady;
            }
            private bool CanAnimate()
            {
                return true;
            }
     
        }
    }
    code behind.cs du class RelayCommand:
    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
     
     
    using System;
    using System.Windows.Input;
    namespace WpfAnimationBlend
    {
        public class MyCommand : ICommand
        {
            private Action _executeMethod;
            private Func<bool> _canExecuteMethod;
     
     
            public MyCommand(Action pexecuteMethod)
            {
                _executeMethod = pexecuteMethod;
            }
            public MyCommand(Action pexecuteMethod, Func<bool> pcanExecuteMethod)
            {
                _executeMethod = pexecuteMethod;
                _canExecuteMethod = pcanExecuteMethod;
            }
     
            private void CanExecuteChanged(MyCommand myCommand, EventArgs eventArgs)
            {
                throw new NotImplementedException();
            }
     
            bool ICommand.CanExecute(object parameter)
            {
                if (_canExecuteMethod != null)
                {
                    return _canExecuteMethod();
                }
                if (_executeMethod != null)
                {
                    return true;
                }
                return false;
            }
     
            void ICommand.Execute(object parameter)
            {
                if (_executeMethod != null)
                {
                    _executeMethod();
                }
            }
     
     
             event EventHandler ICommand.CanExecuteChanged
            {
                add
                {
                    CommandManager.RequerySuggested +=value;
                }
     
                remove
                {
                    CommandManager.RequerySuggested -=value;
     
                }
            }
        }
     
    }
    NB; si tu utilise le pattern MVVM ,la prop CLR et la prop Cmd(de type RelayXommand) doit se trouver dans MainViewModel
    bon code...

Discussions similaires

  1. Gestion des events dans un usercontrol
    Par Aidenam dans le forum Windows Forms
    Réponses: 4
    Dernier message: 02/05/2009, 21h05
  2. [Dojo] Event dans un cellule
    Par MooGle dans le forum Bibliothèques & Frameworks
    Réponses: 1
    Dernier message: 22/05/2007, 18h28
  3. [C#] Thread et events dans une form
    Par farfadet dans le forum Windows Forms
    Réponses: 3
    Dernier message: 21/12/2006, 18h50
  4. un event dans un event
    Par kenny49 dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 04/08/2006, 15h34
  5. [C#] UserControl - Encapsuler icone dans dll ?
    Par dt dans le forum Windows Forms
    Réponses: 21
    Dernier message: 02/11/2005, 12h17

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