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 :

Problème de binding de DataContext d'un ContextMenu en MVVM


Sujet :

Windows Presentation Foundation

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Août 2010
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2010
    Messages : 5
    Par défaut Problème de binding de DataContext d'un ContextMenu en MVVM
    Bonjour a tous,

    Voila j'ai un problème concernant un menu contextuel d'un contrôle TextBox inclue dans le DataTemplate d'une DataGrid.

    Contexte:
    -Projet WPF avec Architecture MVVM
    -Fichier xaml -> DataGrid->DataGridColumn décrit par un DataTemplate contenant un controle TextBox. Ce contrôle TextBox a un controle ContextMenu qui lui est lié.

    Connaissance:
    Un contrôle ContextMenu n'hérite pas du DataContext du contrôle auquel il est lié car ils ne font pas parti du même arbre visuel. Dans ce cas il faut préciser le DataContext du contrôle ContextMenu avec un "Binding" sur l'objet où il est placé.

    Voici un petit exemple pour illustrer mon problème:
    Tout d'abord mes classes
    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
    public class Person
    {
        public string Type { get; set; }
        public string Name { get; set; }
        public string Surname { get; set; }
        public int Age { get; set; }
    }
     
    public class Menu
    {
        public string Name { get; set; }
        public int Code { get; set; }
        public ObservableCollection<Menu> listMenu { get; set; }
    }

    ensuite 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
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
     
    public class MyViewModel : INotifyPropertyChanged
    {
        private ObservableCollection<Person> DataPersons = new ObservableCollection<Person>();
        private ObservableCollection<Menu> DataMenu = new ObservableCollection<Menu>();
     
        public ObservableCollection<Person> listDataPersons { get; set; }
        public ObservableCollection<Menu> listDataMenu { get; set; }
     
        public MyViewModel()
        {
            //initialization
            InitData();
        }
     
        private void InitData()
        {
            listDataPersons = new ObservableCollection<Person>();
            listDataMenu = new ObservableCollection<Menu>();
     
            DataPersons.Add(new Person() { Type = "Friend", Name = "Doe", Surname = "John", Age = 42});
            DataPersons.Add(new Person() { Type = "Friend", Name = "Smith", Surname = "Jack", Age = 42});
     
            DataMenu.Add(new Menu() { Name = "Principal", Code = 1});
            DataMenu.Add(new Menu() { Name = "Secondary", Code = 2});
            DataMenu.Add(new Menu() { Name = "Associated", Code = 3});
     
            DataMenu[2].listMenu = new ObservableCollection<Menu>();
            DataMenu[2].listMenu.Add(new Menu() { Name = "Associated 1", Code = 31 });
     
            listDataPersons = DataPersons;
            listDataMenu = DataMenu;
        }
    }

    Ensuite ma View
    Code xml : 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
     
    <DataGrid ItemsSource="{Binding listDataPersons}" AutoGenerateColumns="False">
            <DataGrid.ContextMenu>
                <ContextMenu ItemsSource="{Binding listDataMenu}"/>
            </DataGrid.ContextMenu>
            <DataGrid.Columns>                
                <DataGridTemplateColumn IsReadOnly="True" Width="*">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <TextBlock Text="{Binding Name}" Width="80" >
                            <TextBlock.ContextMenu>
                                    <ContextMenu ItemsSource="{Binding RelativeSource={RelativeSource Self}, Path=PlacementTarget.DataContext.listDataMenu}"/>
                            </TextBlock.ContextMenu>
                            </TextBlock>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
            </DataGrid.Columns>
        </DataGrid>

    et enfin le code Behind de ma View
    Code c# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    public partial class MyView : UserControl
    {
        public MyView()
        {
            InitializeComponent();
     
            this.DataContext = new MyViewModel();
     
        }
    }

    Mon probleme ici est que le menu contextuel de la DataGrid est bien "Binder" a ma liste ListDataMenu, alors que le menu contextuel lié a la TextBox ne l'est pas. (Click droit sur TextBox => ContextMenu vide; Click droit dans la dataGrid mais en dehors de la TextBox => ContextMenu rempli avec les données de listDataMenu)

  2. #2
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    Regarde les erreurs de binding dans la fenêtre de sortie de VS, en général ça donne des indications utiles

  3. #3
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Août 2010
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2010
    Messages : 5
    Par défaut
    Citation Envoyé par tomlev Voir le message
    Regarde les erreurs de binding dans la fenêtre de sortie de VS, en général ça donne des indications utiles
    Justement dans la fenêtre de sortie VS il n'y as aucune erreurs!!!

    A mon avis cela doit provenir du contrôle ContextMenu qui est assez spécial car même associé a un contrôle "père" ceux-ci ne partage pas leurs arbre visuel (Visual Trees).

    Je suis actuellement en train de regarder du contrôle Popup auquel j'associerai un contrôle Menu pour simuler un menu contextuel mais cela ne nous donne pas de réponse quant a l'histoire du DataContext!!

  4. #4
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Août 2010
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2010
    Messages : 5
    Par défaut
    Salut a tous on m'a finalement guidé vers la solution du probleme conçernant le DataContext.

    Pour Pouvoir passer le DataContext du UserControl au contrôle ContextMenu, il faut le passer a travers la Propirété Tag du contôle TextBox auquel il est associé.

    Voici le code:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    <TextBlock Text="{Binding Name}" Width="80" Tag="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type DataGrid}}, Path=DataContext}">
    	<TextBlock.ContextMenu>                                                                                                
    		<ContextMenu ItemsSource="{Binding RelativeSource={RelativeSource Self}, Path=PlacementTarget.Tag.listDataMenu}" ItemContainerStyle="{StaticResource ContextMenuItemStyle}"/>
    	</TextBlock.ContextMenu>                                
    </TextBlock>

    Pour ceux qui voudrait faire fonctionner mon exemple MVVM vous devrez ajouter les ressources suivante a votre UserControl


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    <UserControl.Resources>
            <HierarchicalDataTemplate DataType="{x:Type cmd:Menu}" ItemsSource="{Binding listMenu}">
                <TextBlock Text="{Binding Path=Name}"/>            
            </HierarchicalDataTemplate>
     
            <Style x:Key="ContextMenuItemStyle">
                <Setter Property="MenuItem.ItemsSource" Value="{Binding Path=listMenu}"/>             
            </Style>
        </UserControl.Resources>

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

Discussions similaires

  1. [WPF] Probléme de binding dans un UserControl :(
    Par UNi[FR] dans le forum Windows Presentation Foundation
    Réponses: 6
    Dernier message: 17/07/2008, 15h51
  2. Probléme avec Bind
    Par rach20032 dans le forum Réseau
    Réponses: 2
    Dernier message: 06/07/2007, 11h36
  3. [Netbeans 6M9 JDk6.1 Matisse] problème de binding
    Par tralloc dans le forum NetBeans
    Réponses: 14
    Dernier message: 21/06/2007, 13h32
  4. problème de bindings avec DropDownList
    Par Vlatiska dans le forum ASP.NET
    Réponses: 14
    Dernier message: 17/03/2007, 14h04
  5. [C#][MySQL 5.x]Problème de Binding
    Par Oufti dans le forum Windows Forms
    Réponses: 2
    Dernier message: 07/05/2006, 23h44

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