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

Silverlight Discussion :

capter un événement dans un TreeView par Binding dans mon ViewModel


Sujet :

Silverlight

  1. #1
    Membre éprouvé
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    876
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Novembre 2005
    Messages : 876
    Par défaut capter un événement dans un TreeView par Binding dans mon ViewModel
    Bonjour,

    Je voudrais capter l'événement "SelectedItemChanged" dans le code suivant:
    Code xaml : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    <sdk:TreeView ItemsSource="{Binding MyTree}"   SelectedItemChanged="{Binding SelectedNode}"  Height="242" HorizontalAlignment="Left" Margin="54,14,0,0" Name="treeView1" VerticalAlignment="Top" Width="294">
                <sdk:TreeView.ItemTemplate >
                    <sdk:HierarchicalDataTemplate ItemsSource="{Binding OcNode}" >
                        <TextBlock Text="{Binding NodeNom}"/>
     
                    </sdk:HierarchicalDataTemplate>
                </sdk:TreeView.ItemTemplate>
            </sdk:TreeView>

    Mon selectedNode est défini comme suit dans mon ViewModel:
    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    public clsNode SelectedNode
            {
                get
                {
                    return _selectedNode;
                }
                set
                {
                    if (_selectedNode != value)
                    {
                        _selectedNode = value;
                        OnPropertyChanged("SelectedNode");
                    }
                }
            }

    Et quand je fais, plutôt qu'un Binding, un eventHandler, mon SelectedItemChanged est bien de type clsNode.

    Quand j'exécute l'application, j'ai le message suivant:
    Failed to assign to property 'System.Windows.Controls.TreeView.SelectedItemChanged'.

  2. #2
    Membre Expert
    Avatar de GuruuMeditation
    Homme Profil pro
    .Net Architect
    Inscrit en
    Octobre 2010
    Messages
    1 705
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : Belgique

    Informations professionnelles :
    Activité : .Net Architect
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2010
    Messages : 1 705
    Par défaut
    Selecteditemchanged est un évent, pas une dependencyproperty, donc elle n'accepte pas de binding!

    Il vaut mieux binder selectedelement sur une property de ton VM, tu détectera le changement dans le setter.style:

    Code c# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
     
    Public itemcclass selecteditem
    {
    get { return blabla;}
    set { 
        Blabla = value;
        // traitement quelconque
        Raisepropertychanged("blabla"); //si mvvmlight
     
        }
    }

  3. #3
    Membre éprouvé
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    876
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Novembre 2005
    Messages : 876
    Par défaut
    Merci pour ta réponse.

    Pourrais-tu être un peu plus explicite quand tu dis:
    Il vaut mieux binder selectedelement sur une property de ton VM, tu détectera le changement dans le setter.style:
    ???

    je n'utilise pas MVVMLight peut-être est-ce la raison ?

  4. #4
    Rédacteur
    Avatar de Nathanael Marchand
    Homme Profil pro
    Expert .Net So@t
    Inscrit en
    Octobre 2008
    Messages
    3 615
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Expert .Net So@t
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2008
    Messages : 3 615
    Par défaut
    Ca n'est pas sur SelectedItemChanged (qui est un évènement) auquel il faut se brancher mais SelectedItem (comme précisé par Olivier).

    Si tu souhaites vraiment te brancher sur l'évènement il faut que tu utilises une ICommand et un EventToCommand (comme celui du SDK Blend)

  5. #5
    Membre éprouvé
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    876
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Novembre 2005
    Messages : 876
    Par défaut
    d'ou mon incompréhension...

    il n'y a pas de SelectedItem dans le TreeView !

  6. #6
    Rédacteur
    Avatar de Nathanael Marchand
    Homme Profil pro
    Expert .Net So@t
    Inscrit en
    Octobre 2008
    Messages
    3 615
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Expert .Net So@t
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2008
    Messages : 3 615
    Par défaut
    Haha! Effectivement c'est plus dur
    Donc il faut que tu récuperes le sdk Blend. Dedans y'a deux dll interessantes: System.Windows.Interactivity et Microsoft.Expression.Interactions
    Ensuite tu crées une ICommand dans ton ViewModel et enfin tu fais un truc du genre:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    <sdk:TreeView ItemsSource="{Binding MyTree}" Height="242" HorizontalAlignment="Left" Margin="54,14,0,0" Name="treeView1" VerticalAlignment="Top" Width="294">
        <i:Interaction.Triggers>
            <i:EventTrigger EventName="SelectedItemChanged">
                <i:InvokeCommandAction Command="{Binding MaICommande}" />
            </i:EventTrigger>
        </i:Interaction.Triggers>
        <sdk:TreeView.ItemTemplate >
            <sdk:HierarchicalDataTemplate ItemsSource="{Binding OcNode}" >
                <TextBlock Text="{Binding NodeNom}"/>
            </sdk:HierarchicalDataTemplate>
        </sdk:TreeView.ItemTemplate>
    </sdk:TreeView>
    Ta commande sera appellée à chaque changement de l'item

  7. #7
    Membre Expert
    Avatar de GuruuMeditation
    Homme Profil pro
    .Net Architect
    Inscrit en
    Octobre 2010
    Messages
    1 705
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : Belgique

    Informations professionnelles :
    Activité : .Net Architect
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2010
    Messages : 1 705
    Par défaut
    Quand je dis qu'il faut binder sur une proprieté de ton ViewModel c'est que vu que ton ViewModel gère et présente les données, il est logique ce celui-ci ait un propriété qui est l'objet selectionné de ton treeview.

    Donc, tu crée une propriété qui sera bindée à au selecteditem du treeview (pour faire le lien entre le viewmodel et la vue).

    Dans le setter de la propriété, il faut (dans la plupart des cas) rafraichir le binding, comme ça si tu modifies l'objet selectionné dans le VueModel (via du code), le changement sera reflété dans le treeview (sinon le treeview en se mettra pas a jour et il restera sur l'ancienne selection).
    Pour ce faire, soit utiliser RaisePropertyChanged (si tu as MVVM Light) ou alors, à la main, il faut implémenter INotifyPropertyChanged dans ton ViewModel. (RaisePropertyChanged est une implémentation de INotifyPropertyChanged déja prête dans MVVMLight)

    Si tu as d'autres question, n'hésite pas!

  8. #8
    Membre éprouvé
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    876
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Novembre 2005
    Messages : 876
    Par défaut
    Citation Envoyé par GuruuMeditation Voir le message
    Quand je dis qu'il faut binder sur une proprieté de ton ViewModel c'est que vu que ton ViewModel gère et présente les données, il est logique ce celui-ci ait un propriété qui est l'objet selectionné de ton treeview.

    Donc, tu crée une propriété qui sera bindée à au selecteditem du treeview (pour faire le lien entre le viewmodel et la vue).
    On est d'accord sur la manière dont interragissent ViewModel et View

    Mais..., il n'y a pas de "SelectedItem" dans le TreeView (coté XAML !!!)

    Je vais donc tenter la proposition de Nathanael.

  9. #9
    Membre éprouvé
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    876
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Novembre 2005
    Messages : 876
    Par défaut
    Citation Envoyé par Nathanael Marchand Voir le message
    Ta commande sera appellée à chaque changement de l'item
    Bon effectivement ça marche et ma commande est appelée à chaque changement d'Item, mais ça ne me permet pas de passer à mon ViewModel quel item de mon TreeView a été sélectionné

  10. #10
    Rédacteur
    Avatar de Nathanael Marchand
    Homme Profil pro
    Expert .Net So@t
    Inscrit en
    Octobre 2008
    Messages
    3 615
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Expert .Net So@t
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2008
    Messages : 3 615
    Par défaut
    Alors pour cela, dans le MVVM Light Toolkit il y'a une classe magique
    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
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    // ****************************************************************************
    // <copyright file="EventToCommand.cs" company="GalaSoft Laurent Bugnion">
    // Copyright © GalaSoft Laurent Bugnion 2009-2011
    // </copyright>
    // ****************************************************************************
    // <author>Laurent Bugnion</author>
    // <email>laurent@galasoft.ch</email>
    // <date>3.11.2009</date>
    // <project>GalaSoft.MvvmLight.Extras</project>
    // <web>http://www.galasoft.ch</web>
    // <license>
    // See license.txt in this solution or http://www.galasoft.ch/license_MIT.txt
    // </license>
    // <LastBaseLevel>BL0002</LastBaseLevel>
    // ****************************************************************************
     
    using System;
    using System.Windows;
    using System.Windows.Input;
    using System.Windows.Interactivity;
     
    ////using GalaSoft.Utilities.Attributes;
     
    namespace GalaSoft.MvvmLight.Command
    {
        /// <summary>
        /// This <see cref="System.Windows.Interactivity.TriggerAction" /> can be
        /// used to bind any event on any FrameworkElement to an <see cref="ICommand" />.
        /// Typically, this element is used in XAML to connect the attached element
        /// to a command located in a ViewModel. This trigger can only be attached
        /// to a FrameworkElement or a class deriving from FrameworkElement.
        /// <para>To access the EventArgs of the fired event, use a RelayCommand&lt;EventArgs&gt;
        /// and leave the CommandParameter and CommandParameterValue empty!</para>
        /// </summary>
        ////[ClassInfo(typeof(EventToCommand),
        ////  VersionString = "3.0.0.0",
        ////  DateString = "201003041420",
        ////  Description = "A Trigger used to bind any event to an ICommand.",
        ////  UrlContacts = "http://www.galasoft.ch/contact_en.html",
        ////  Email = "laurent@galasoft.ch")]
        public partial class EventToCommand : TriggerAction<DependencyObject>
        {
            /// <summary>
            /// Gets or sets a value indicating whether the EventArgs passed to the
            /// event handler will be forwarded to the ICommand's Execute method
            /// when the event is fired (if the bound ICommand accepts an argument
            /// of type EventArgs).
            /// <para>For example, use a RelayCommand&lt;MouseEventArgs&gt; to get
            /// the arguments of a MouseMove event.</para>
            /// </summary>
            public bool PassEventArgsToCommand
            {
                get;
                set;
            }
     
            /// <summary>
            /// Provides a simple way to invoke this trigger programatically
            /// without any EventArgs.
            /// </summary>
            public void Invoke()
            {
                Invoke(null);
            }
     
            /// <summary>
            /// Executes the trigger.
            /// <para>To access the EventArgs of the fired event, use a RelayCommand&lt;EventArgs&gt;
            /// and leave the CommandParameter and CommandParameterValue empty!</para>
            /// </summary>
            /// <param name="parameter">The EventArgs of the fired event.</param>
            protected override void Invoke(object parameter)
            {
                if (AssociatedElementIsDisabled())
                {
                    return;
                }
     
                var command = GetCommand();
                var commandParameter = CommandParameterValue;
     
                if (commandParameter == null
                    && PassEventArgsToCommand)
                {
                    commandParameter = parameter;
                }
     
                if (command != null
                    && command.CanExecute(commandParameter))
                {
                    command.Execute(commandParameter);
                }
            }
     
            private static void OnCommandChanged(
                EventToCommand element,
                DependencyPropertyChangedEventArgs e)
            {
                if (element == null)
                {
                    return;
                }
     
                if (e.OldValue != null)
                {
                    ((ICommand) e.OldValue).CanExecuteChanged -= element.OnCommandCanExecuteChanged;
                }
     
                var command = (ICommand) e.NewValue;
     
                if (command != null)
                {
                    command.CanExecuteChanged += element.OnCommandCanExecuteChanged;
                }
     
                element.EnableDisableElement();
            }
     
            private bool AssociatedElementIsDisabled()
            {
                var element = GetAssociatedObject();
                return AssociatedObject == null
                    || (element != null
                       && !element.IsEnabled);
            }
     
            private void EnableDisableElement()
            {
                var element = GetAssociatedObject();
     
                if (element == null)
                {
                    return;
                }
     
                var command = this.GetCommand();
     
                if (this.MustToggleIsEnabledValue
                    && command != null)
                {
                    element.IsEnabled = command.CanExecute(this.CommandParameterValue);
                }
            }
     
            private void OnCommandCanExecuteChanged(object sender, EventArgs e)
            {
                EnableDisableElement();
            }
        }
    }
    Si tu mets PassEventArgsToCommand à true, dans ta méthode d'execution de la commande, tu peux récuperer le EventArgs de l'évènement et dans cet item il y a le noeud!

  11. #11
    Membre éprouvé
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    876
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Novembre 2005
    Messages : 876
    Par défaut
    Merci pour cette précision.

    J'ai toujours été un peu réticent à utiliser MVVM light me demandant quelle serait sa portabilité en cas d'évolution de version (SL5 par exemple).

    De plus, en passant par le code behind (en faisant donc une entorse à MVVM) je peux déjà savoir quel noeud est cliqué et mettre ma propriété "SelectedNode" à jour dans mon ViewModel.

    Par contre je ne pense pas que MVVM Light me permettra de faire du "TwoWays", c-à-d que si je change dans mon ViewModel mon SelectedNode, mon TreeView dans ma vue se mette à jour.

  12. #12
    Rédacteur
    Avatar de Nathanael Marchand
    Homme Profil pro
    Expert .Net So@t
    Inscrit en
    Octobre 2008
    Messages
    3 615
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Expert .Net So@t
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2008
    Messages : 3 615
    Par défaut
    Citation Envoyé par Golzinne Voir le message
    Merci pour cette précision.

    J'ai toujours été un peu réticent à utiliser MVVM light me demandant quelle serait sa portabilité en cas d'évolution de version (SL5 par exemple).

    De plus, en passant par le code behind (en faisant donc une entorse à MVVM) je peux déjà savoir quel noeud est cliqué et mettre ma propriété "SelectedNode" à jour dans mon ViewModel.

    Par contre je ne pense pas que MVVM Light me permettra de faire du "TwoWays", c-à-d que si je change dans mon ViewModel mon SelectedNode, mon TreeView dans ma vue se mette à jour.
    Pour MVVM Light Toolkit, elle targete tous les frameworks (.Net 3.5, .Net4, SL3, SL4 & WP7) donc niveau portabilité on ne peut pas se plaindre.
    Après, c'est ce que j'ai fait dans mon projet, tu peux utiliser juste le code source de cette classe sans utiliser tout MVVM Light.

    Effectivement, pour le TwoWays, c'est rapé :\ Cela dit, le GridView est un des éléments les plus dur à utiliser avec MVVM (avec la multiselection dans une ListBox/DataGrid)

  13. #13
    Membre éprouvé
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    876
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Novembre 2005
    Messages : 876
    Par défaut
    OK,

    Merci pour tous les tuyaux, je marque donc ce poste comme "Résolu" puisque je pense qu'on n'arrivera pas plus près d'une solution qui me convienne.

    Bon WE

  14. #14
    Expert confirmé
    Avatar de Skyounet
    Homme Profil pro
    Software Engineer
    Inscrit en
    Mars 2005
    Messages
    6 380
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Software Engineer
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 6 380
    Par défaut
    Malgré le fait que SelectedItem soit en lecture seule, on doit surement pouvoir le passer en paramètre de la commande via CommandParameter.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <InvokeCommandAction Command="{Binding MaICommande}" CommandParameter="{Binding Path=SelectedItem, ElementName=treeView1}" />

  15. #15
    Membre éprouvé
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    876
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Novembre 2005
    Messages : 876
    Par défaut
    Merci Skyounet,

    Peux-tu m'indiquer comment récupérer le paramètre dans mon ViewModel ?

    Autre question, j'ai trouvé un article intéressant qui semble répondre au besoin du "SelectedItem" mode TwoWays....

    Qu'en penses-tu ?

    http://weblogs.asp.net/cibrax/archiv...w-control.aspx

  16. #16
    Expert confirmé
    Avatar de Skyounet
    Homme Profil pro
    Software Engineer
    Inscrit en
    Mars 2005
    Messages
    6 380
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Software Engineer
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 6 380
    Par défaut
    Citation Envoyé par Golzinne Voir le message
    Merci Skyounet,

    Peux-tu m'indiquer comment récupérer le paramètre dans mon ViewModel ?
    Dans le parametre de ta ICommand

    Code c# : Sélectionner tout - Visualiser dans une fenêtre à part
    new RelayCommand<TaClasse>(c => /* ici c est le SelectedItem */ );

    Apres faut remplacer RelayCommand par ta propre implementation generique de ICommand.

    Autre question, j'ai trouvé un article intéressant qui semble répondre au besoin du "SelectedItem" mode TwoWays....

    Qu'en penses-tu ?
    Bof. Perso je serai plus du genre a creer un Attached Property (MySelectedItem par exemple) pour le TreeView qui refleterait le vrai SelectedItem mais en get/set couple avec un behavior qui check le SelectedItemChanged.

    Code c# : 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
    public class TreeViewExtensions
    {
        public static object GetMySelectedItem(TreeView obj)
        {
            return (object)obj.GetValue(MySelectedItemProperty);
        }
     
        public static void SetMySelectedItem(TreeView obj, object value)
        {
            obj.SetValue(MySelectedItemProperty, value);
        }
     
        // Using a DependencyProperty as the backing store for MySelectedItem.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty MySelectedItemProperty =
            DependencyProperty.RegisterAttached("MySelectedItem", typeof(object), typeof(TreeViewExtensions), new PropertyMetadata(new PropertyChangedCallback(OnMySelectedItemChanged)));
     
        private static void OnMySelectedItemChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            var treeView = sender as TreeView;
            treeView.SelectItem(e.NewValue);
        }
    }
     
    public class TreeViewSelectionChangedBehavior : System.Windows.Interactivity.Behavior<TreeView>
    {
        protected override void OnAttached()
        {
            base.OnAttached();
     
            AssociatedObject.SelectedItemChanged += new RoutedPropertyChangedEventHandler<object>(AssociatedObject_SelectedItemChanged);
        }
     
        protected override void OnDetaching()
        {
            base.OnDetaching();
     
            AssociatedObject.SelectedItemChanged -= new RoutedPropertyChangedEventHandler<object>(AssociatedObject_SelectedItemChanged);
        }
     
        void AssociatedObject_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
        {
            TreeViewExtensions.SetMySelectedItem(AssociatedObject, e.NewValue);
        }
    }

    Pas teste, donc je sais pas si ca fonctionne
    Apres il faut juste attache le behavior a ton TreeView et faire du binding sur l'attached property.

  17. #17
    Membre Expert
    Avatar de Samuel Blanchard
    Homme Profil pro
    Expert .NET
    Inscrit en
    Février 2010
    Messages
    1 504
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France

    Informations professionnelles :
    Activité : Expert .NET

    Informations forums :
    Inscription : Février 2010
    Messages : 1 504
    Par défaut
    J'aurais fait comme Sky (C'est constructif ça) !

  18. #18
    Membre éprouvé
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    876
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Novembre 2005
    Messages : 876
    Par défaut
    Citation Envoyé par Skyounet Voir le message
    Dans le parametre de ta ICommand

    Code c# : Sélectionner tout - Visualiser dans une fenêtre à part
    new RelayCommand<TaClasse>(c => /* ici c est le SelectedItem */ );

    Apres faut remplacer RelayCommand par ta propre implementation generique de ICommand.

    Cher MVP , je ne suis pas sûr de pouvoir faire ma propre implémentation de ma RelayCommand puisque je ne comprend déjà qu'à moitié l'existante, que j'ai bien sûr piqué quelque part...

    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
     public class RelayCommand : ICommand
        {
            private Action _handler;
            public RelayCommand(Action handler)
            {
                _handler = handler;
            }
     
            private bool _isEnabled;
            public bool IsEnabled
            {
                get { return _isEnabled; }
                set
                {
                    if (value != _isEnabled)
                    {
                        _isEnabled = value;
                        if (CanExecuteChanged != null)
                        {
                            CanExecuteChanged(this, EventArgs.Empty);
                        }
                    }
                }
            }
     
            public bool CanExecute(object parameter)
            {
                return IsEnabled;
            }
     
            public event EventHandler CanExecuteChanged;
     
            public void Execute(object parameter)
            {
                _handler();
            }
        }
    Pour l'instant je l'utilise comme suit:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     
           private RelayCommand _selectedTreeCommand;
     
           // dans le constructeur, je mets:
                _selectedTreeCommand = new RelayCommand(ClickTreeView) { IsEnabled = true };
           // fin du constructeur
     
      private void ClickTreeView()
            {
                MessageBox.Show("treeViewItem Selected");
            }
     
     public ICommand SelectedTreeCommand
            {
                get { return _selectedTreeCommand; }
            }

  19. #19
    Expert confirmé
    Avatar de Skyounet
    Homme Profil pro
    Software Engineer
    Inscrit en
    Mars 2005
    Messages
    6 380
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Software Engineer
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 6 380
    Par défaut
    Tu peux prendre la mienne si tu veux

    Code c# : 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
    public class RelayCommand : ICommand
    {
        private readonly Action action;
        private readonly Func<bool> canExecute;
     
        protected RelayCommand() { }
     
        public RelayCommand(Action action, Func<bool> canExecute = null)
        {
            this.action = action;
            this.canExecute = canExecute;
        }
     
        public virtual bool CanExecute(object parameter = null)
        {
            return canExecute != null ? canExecute() : true;
        }
     
        public event EventHandler CanExecuteChanged;
     
        public virtual void Execute(object parameter = null)
        {
            if (CanExecute()) action();
        }
     
        public void RaiseCanExecuteChanged()
        {
            if (CanExecuteChanged != null) CanExecuteChanged(this, EventArgs.Empty);
        }
    }
     
    public class RelayCommand<T> : RelayCommand
    {
        private readonly Action<T> action;
        private readonly Predicate<T> canExecute;
     
        public RelayCommand(Action<T> action, Predicate<T> canExecute = null)
        {
            this.action = action;
            this.canExecute = canExecute;
        }
     
        public override bool CanExecute(object parameter = null)
        {
            return canExecute != null ? parameter is T && canExecute((T)parameter) : true;
        }
     
        public override void Execute(object parameter = null)
        {
            if (CanExecute(parameter)) action((T)parameter);
        }
    }

    En utilisant RelayCommand<T> tu devrais pouvoir faire ce que tu veux.

  20. #20
    Membre éprouvé
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    876
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Novembre 2005
    Messages : 876
    Par défaut
    Citation Envoyé par Skyounet Voir le message
    Tu peux prendre la mienne si tu veux
    ...
    En utilisant RelayCommand<T> tu devrais pouvoir faire ce que tu veux.
    Bon voilà, j'ai pris la tienne

    par contre, sachant que le SelectedItem de mon treeView est un "clsNode", je n'arrive pas à récupérer mon clsNode.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     private RelayCommand<clsNode> _selectedTreeCommand;
    
     _selectedTreeCommand = new RelayCommand(ClickTreeView(???)) ;
      
    
      private void ClickTreeView(clsNode myNode)
            {
               // ici je devrais accéder à mon clsNode ??
                MessageBox.Show("treeViewItem Selected");
            }
    
    
     public ICommand SelectedTreeCommand        {
                get { return _selectedTreeCommand ????; }
            }
    Je n'arrive pas à écrire le code ci-dessus, peux-tu m'aider ?

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Réponses: 1
    Dernier message: 15/10/2013, 10h46
  2. Réponses: 3
    Dernier message: 06/04/2011, 11h44
  3. Listview dans un treeview en binding
    Par silberfab dans le forum Windows Presentation Foundation
    Réponses: 1
    Dernier message: 07/04/2009, 17h26
  4. Ajout de nodes dans un treeview par le client en asp.net
    Par thewaterkidny dans le forum ASP.NET
    Réponses: 3
    Dernier message: 23/04/2007, 17h24
  5. Réponses: 5
    Dernier message: 09/01/2003, 11h55

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