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 :

[Interaction WPF/C#]Reliè un evenement d'une classe a la fonction d'une autre classe


Sujet :

Windows Presentation Foundation

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    612
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 612
    Points : 338
    Points
    338
    Par défaut [Interaction WPF/C#]Reliè un evenement d'une classe a la fonction d'une autre classe
    Bonjour,

    Je tente de personnaliser une TreeView afin d'afficher des Map et des Epaisseur
    une Map pouvant contenir plusieurs Epaisseur

    Nous avons donc au maximum 2 niveau.


    Pour alleger le code source WPF j'ai mis en place un Dictionnaire de Ressource pour mes Styles et Template

    une partie du Dictionnaire de Ressource
    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
    <ResourceDictionary x:Class="MedievalWars_Mapping.dictionaryStyle"
                        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                        xmlns:cc="clr-namespace:MedievalWars_Mapping"
                        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
     
        <!-- DataTemplate d'un Element Map -->
        <HierarchicalDataTemplate x:Key="dtMap" ItemsSource="{Binding SubItems}">
            <TextBlock Foreground="Black" Text="{Binding Identifiant}">
                <TextBlock.ContextMenu>
                    <ContextMenu Name="ctmMap">
                        <MenuItem Header="Ajouter Epaisseur" Click="MenuItem_AjouterEpaisseur_Click" />
                        <Separator />
                        <MenuItem Header="Parametrer"/>
                        <MenuItem Header="Supprimer" />
                    </ContextMenu>
                </TextBlock.ContextMenu>
            </TextBlock>
        </HierarchicalDataTemplate>
    </ResourceDictionary>
    winPrincipal contient une TreeView qui possede des Items beneficiant du HierarchicalDataTemplate ci-dessus. Ce Template ajoute un menu contextuel et maintenant j'aimerais ajouter la fonction correspondant au Click des elements du menu


    le 1er solution me venant a l'esprit et d'ajouter
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    public partial class dictionaryStyle
    {
        public void MenuItem_AjouterEpaisseur_Click(object sender, RoutedEventArgs e)
        {
            MessageBox.Show("test ajout epaisseur in ds class : OK!!");
        }
    }
    avec a la place de MessageBox(c'était pour des test) le declanchement de la fonction adequat dans winPrincipal avec tout ce que cela implique(gestion de l'instance de winPrincipal.....)

    ma question est donc, n'y a t-il pas un moyen plus simple de mettre en relation mon Dictionnaire de Ressource et ma Fenetre???

    EDIT: il faudrais ausi que je puisse acceder a mes MenuItem pour leur assigner une Icon en C#, je recupere l'icon depuis une fonction d'une librairie

    merci

  2. #2
    Rédacteur
    Avatar de Thomas Lebrun
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    9 161
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 9 161
    Points : 19 434
    Points
    19 434
    Par défaut
    Tu veux pas réexpliquer ? Car j'ai rien compris

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    612
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 612
    Points : 338
    Points
    338
    Par défaut
    ok

    je possede une fenetre de type winPrincipal
    cette fenetre possede une TreeView qui represente(via ItemsSource) une classe

    cette classe herite de ObservableCollection<Map> et l'objet Map herite de ObservableCollection<Epaisseur>


    nous avons donc une TreeView representant une liste de Map (noeud de 1er niveau) et chaque Map possede une liste d'Epaisseur (noeud de 2ème niveau)

    -> winPrincipal
    ---> TreeView
    -----> Map1
    -------> Epaisseur1
    -------> Epaisseur2
    -------> Epaisseur3
    -----> Map2
    -------> Epaisseur4
    -------> Epaisseur5
    -------> Epaisseur6
    Pour mettre en forme tout sa de maniere clair je stock tout mes Style et Template dans une RessourceDictionary.

    voici une partie du dictionnaire de ressource
    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
    <ResourceDictionary x:Class="MedievalWars_Mapping.dictionaryStyle"
                        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                        xmlns:cc="clr-namespace:MedievalWars_Mapping"
                        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
     
        <!-- DataTemplate d'un Element Map -->
        <HierarchicalDataTemplate x:Key="dtMap" ItemsSource="{Binding SubItems}">
            <TextBlock Foreground="Black" Text="{Binding Identifiant}">
                <TextBlock.ContextMenu>
                    <ContextMenu Name="ctmMap">
                        <MenuItem Header="Ajouter Epaisseur" Click="MenuItem_AjouterEpaisseur_Click" />
                        <Separator />
                        <MenuItem Header="Parametrer"/>
                        <MenuItem Header="Supprimer" />
                    </ContextMenu>
                </TextBlock.ContextMenu>
            </TextBlock>
        </HierarchicalDataTemplate>
    </ResourceDictionary>
    chaque Map s'affiche de la maniere suivante:
    -> Une Map et representer pas un TextBlock affichant l'Identifiant de la Map
    -> Le TextBlock possede un Menu Contextuel a afficher sur clique droit
    -> Le menu contextuel possede des MenuItem pour chaque action
    -> Chaque MenuItem declenche un evenement Click


    mon problème:
    1) pouvoir assigner au evenement Click une fonction se trouvant dans winPrincipal.cs

    2) assigner une Icon au MenuItem depuis le C#
    exemple: a l'instanciation de winPrincipal definir l'Icon par....
    je ne peut le mettre "en dur" car l'image est stocker dans une dll


    Merci


    j'ai testè une premiere solution qui fonctionne:
    PS: c'est pas clair du tout pour la solution mais je ne peut pas trop prendre de temps le cour touche a sa fin....

    j'ajoute une partial class du meme nom que mon dictionaire de ressource
    les fonction click des MenuItem sont generer dans cette nouvelle classe
    ces fonctions declenche d'autre fonction dans winPrincipal

    cela implique que les fonction dans winPrincipal soit static

  4. #4
    Rédacteur
    Avatar de Thomas Lebrun
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    9 161
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 9 161
    Points : 19 434
    Points
    19 434
    Par défaut
    Citation Envoyé par TheBlackReverand Voir le message
    1) pouvoir assigner au evenement Click une fonction se trouvant dans winPrincipal.cs
    Il est là le problème: ce n'est pas le plus "propre" d'appeler une méthode de ta classe principale. Tu devrais plutôt mettre ta méthode dans une classe (statique) Helper qui sera accessible depuis n'importe où

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    612
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 612
    Points : 338
    Points
    338
    Par défaut
    ok donc si j'ai bien compris passer par un intermediaire qui serais static?

    si j'ai bien compris je suis sur le meme principe

    Extrait du Dictionnaire de Ressource contenant le menu contextuel
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
        <HierarchicalDataTemplate x:Key="dtMap" ItemsSource="{Binding SubItems}">
            <TextBlock Foreground="Black" Text="{Binding Identifiant}">
                <TextBlock.ContextMenu>
                    <ContextMenu Name="ctmMap">
                        <MenuItem Name="mnuAjouterEpaisseur" Header="Ajouter Epaisseur" Click="MenuItem_AjouterEpaisseur_Click" />
                        <Separator />
                        <MenuItem Name="mnuParametrerMap"  Header="Parametrer" Click="MenuItem_ParametreMap_Click"/>
                        <MenuItem Name="mnuSupprimerMap" Header="Supprimer" Click="MenuItem_SupprimerMap_Click" />
                    </ContextMenu>
                </TextBlock.ContextMenu>
            </TextBlock>
        </HierarchicalDataTemplate>
    Classe assigner au dictionnaire de ressource; contient les fonctions declencher par les evenements
    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
        public partial class dictionaryStyle
        {
            private void MenuItem_ParametreMap_Click(object sender, RoutedEventArgs e)
            {
                winPrincipal.MenuItem_AjouterEpaisseur_Click(sender, e);
            }
            private void MenuItem_SupprimerMap_Click(object sender, RoutedEventArgs e)
            {
                winPrincipal.MenuItem_SupprimerMap_Click(sender, e);
            }
     
            private void MenuItem_AjouterEpaisseur_Click(object sender, RoutedEventArgs e)
            {
                winPrincipal.MenuItem_AjouterEpaisseur_Click(sender, e);
            }
        }
    Fonction de la fenetre principale(winPrincipal)
    cette fonction contiendras le code fonctionnel
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
            internal static void MenuItem_SupprimerMap_Click(object sender, RoutedEventArgs e)
            {
     
            }
    qu'entendez vous par "code propre" ??

    dans les norme? securiser? comprehensible/lisible??

  6. #6
    Rédacteur
    Avatar de Thomas Lebrun
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    9 161
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 9 161
    Points : 19 434
    Points
    19 434
    Par défaut
    Non, dans ton code, tu ne dois pas faire:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    winPrincipal.MenuItem_AjouterEpaisseur_Click(sender, e);
    Tu dois passer par ta classe helper: il ne faut pas faire référence à ta classe principale:


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Tools.AjouterEpaisseur();
    Par code propre, je veux parler de bonnes pratiques

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    612
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 612
    Points : 338
    Points
    338
    Par défaut
    il est vrai que en y reflechissant mieu il n'y a aucune raison que le code de mes fonctions se trouve dans winPrincipal. en effet le code n'influence que sur la collection de map.

    la collection de map étant utiliser comme ItemsSource la fenetre ma TreeView doit s'actualiser seul.


    Je viens de fair les modification et sa ne marche qu'a moitiè

    si j'ajoute une Epaisseur elle est automatiquement ajouter dans mon TreeView
    mais si je modifier le nom de la Map le TreeView ne se met pas a jour

    dans les 2 cas je modifie l'objet directement dans le Catalogue
    ainsi la seul difference et que Map est un noeud principal et Epaisseur un noeud secondaire

  8. #8
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    612
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 612
    Points : 338
    Points
    338
    Par défaut
    il me rester un problème, la TreeView, reliè a une ObservableCollection<T> par l'intermediaire de ItemsSource ne se metter pas a jour correctement.

    si je faisais un ajout ou une suppression sa fonctionner mais pas lorsque je modifier un element de la Collection(a moins que le element de la collection doivent eu ausi implementer une class/interface??)

    en tout cas pour ce que cela interresse, on peut forcer la reactualisation des tout les controle relier a la ObservableCollection<T> avec

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    public void Update()
    {
        OnCollectionChanged(new NotifyCollectionChangedEventArgs
            (NotifyCollectionChangedAction.Reset));
    }
    dans le cas present la recharge est total (si vous avais un noeud d'ouvert dans votre TreeView il ne le seras plus, la TreeView et remise a zero puis a nouveau rempli)

    il faut donc pousser un peut vers le type d'action

    maintenant lorsque je fait une modification sur UNE INFORMATION VISIBLE (sinon aucun interet de re-actualiser les controle) je fait appel a "Update()"

  9. #9
    Rédacteur
    Avatar de Thomas Lebrun
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    9 161
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 9 161
    Points : 19 434
    Points
    19 434
    Par défaut
    Citation Envoyé par TheBlackReverand Voir le message
    (a moins que le element de la collection doivent eu ausi implementer une class/interface??)
    Oui, les éléments doivent implémenter INotifyPropertyChanged

  10. #10
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    612
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 612
    Points : 338
    Points
    338
    Par défaut


    merci

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

Discussions similaires

  1. Réponses: 4
    Dernier message: 10/05/2007, 15h41
  2. Réponses: 10
    Dernier message: 21/02/2007, 09h58
  3. Modifier une image dynamiquement en fonction d'une liste
    Par metatron dans le forum Général JavaScript
    Réponses: 4
    Dernier message: 26/11/2006, 17h33
  4. Réponses: 4
    Dernier message: 31/10/2006, 19h03
  5. Réponses: 13
    Dernier message: 21/06/2006, 19h36

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