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 :

Récupérer le DataContext du Parent.Parent


Sujet :

Silverlight

  1. #1
    Membre confirmé Avatar de cyberbobby
    Inscrit en
    Février 2009
    Messages
    171
    Détails du profil
    Informations forums :
    Inscription : Février 2009
    Messages : 171
    Par défaut Récupérer le DataContext du Parent.Parent
    Bonsoir,

    Petite question Binding.

    Dans le DataTemplate d'une ListBox, j'aimerais Binder un élément sur mon ViewModel.

    Ils sont évidemment tous bindés sur l'ItemSource. Et j'aimerais que mon contrôle Border (voir code ci-dessous) soit bindé sur le DataContext de mon UserControl.

    J'ai bricolé une solution via l'événement loaded. Le problème est que lorsque je modifie le DataContext de ma Border, ma TextBox en hérite, hors j'aimerais qu'il garde celui de l'ItemSource. (Donc, je dois repasser par un événement Loaded pour ressetter le DataContext de la TextBox).

    Je trouve évidemment ma solution fort dégueulasse et j'aurais voulu savoir comment je pouvais binder le DataContext de ma TextBox sur celui de mon StackPanel (DataContext="{Binding Parent.Parent.DataContext}" ne fonctionne pas).

    J'espère que vous aurez compris quelque chose à ma question

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
     <ListBox.ItemTemplate>
        <DataTemplate>
           <StackPanel x:Name="SPTemplate" Orientation="Horizontal" Loaded="SPTemplate_Loaded">
                <Border Loaded="Border_Loaded" Style="{StaticResource BrdTemplate}" Visibility="{Binding Preferences.IsAPT, Converter={StaticResource ConverterDoubletoString}, ConverterParameter=preferences}">
                       <TextBox Loaded="TextBox_Loaded" Text="{Binding BudgetTon.Value,  Converter={StaticResource ConverterDoubletoString}, ConverterParameter=value}" Style="{StaticResource TBTemplate}"/>
                </Border>
            </StackPanel>
        </DataTemplate>
    </ListBox.ItemTemplate>
    Merci ;-)

  2. #2
    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
    As-tu essayé avec ElementName comme source ? Attention pas sur ton element StackPanel (car il me semble que cela ne fonctionne pas dans un ItemTemplate) mais sur un element extérieur, comme ta ListBox (le datacontext de celle-ci sera le même que pour ton StackPanel).

    J'ai un article sur mon blog qui parle de ça :

    http://blog.naviso.fr/wordpress/?p=39

  3. #3
    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 Samoteph Voir le message
    As-tu essayé avec ElementName comme source ? Attention pas sur ton element StackPanel (car il me semble que cela ne fonctionne pas dans un ItemTemplate) mais sur un element extérieur, comme ta ListBox (le datacontext de celle-ci sera le même que pour ton StackPanel).

    J'ai un article sur mon blog qui parle de ça :

    http://blog.naviso.fr/wordpress/?p=39
    Ben le soucis avec ta solution c'est que s'il prends le DataContext de la listbox ce sera un IEnumerable<T>.

    Le binding sur le StackPanel aurait fonctionné je pense mais si ça ne marche pas ben ça marchera pas (ça doit venir du fait que le name n'est plus unique une fois le rendu de la ListBox effectué).

    Le truc c'est qu'il faille que le Border soit bindé sur un object et un le TextBlock contenu dans le border soit bindé sur l'object bindé au ListBoxItem.

  4. #4
    Membre confirmé Avatar de cyberbobby
    Inscrit en
    Février 2009
    Messages
    171
    Détails du profil
    Informations forums :
    Inscription : Février 2009
    Messages : 171
    Par défaut
    Merci pour vos réponses

    Non, avec ElementName je n'ai pas essayé.

    Je teste ça demain et je reviens vers vous (en bien ou en mal ;-))

    Merci !

  5. #5
    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
    Ben le soucis avec ta solution c'est que s'il prends le DataContext de la listbox ce sera un IEnumerable<T>.
    Mais la question n'est-elle pas celle-ci ?

    Et j'aimerais que mon contrôle Border (voir code ci-dessous) soit bindé sur le DataContext de mon UserControl
    Comme le datacontext du usercontrol est apparement le même que celui de la listbox, je voulais binder sur le datacontext de la listbox et non sur l'itemSource. J'ai mal compris le problème ?

  6. #6
    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 Samoteph Voir le message
    Mais la question n'est-elle pas celle-ci ?



    Comme le datacontext du usercontrol est apparement le même que celui de la listbox, je voulais binder sur le datacontext de la listbox et non sur l'itemSource. J'ai mal compris le problème ?
    De ce que j'ai compris il souhaiterais que son Border soit bindé sur le DataContext de l'UC, qui fonctionne avec le ElementName, mais il souhaite que le TextBlock enfant continue d'être bindé sur le même DataContext que le ListBoxItem, or en settant le DataContext du Border ça va aussi setter celui du TextBlock.

  7. #7
    Membre confirmé Avatar de cyberbobby
    Inscrit en
    Février 2009
    Messages
    171
    Détails du profil
    Informations forums :
    Inscription : Février 2009
    Messages : 171
    Par défaut
    Oui en effet, Skyounet, c'est bien ça !

    Mais je voulais utiliser ElementName pour les deux en fait.

    Un pour Binder le DataContext de ma Border sur le UC.
    Et ensuite binder le DataContext de mon TextBlock sur mon StackPanel par exemple.

    Tu penses que ça ne fonctionnera pas ?

  8. #8
    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
    D'accord, il y a une partie de la question que je n'avais pas captée

    je pense qu'en mettant comme source un elementname avec element externe sur le border et un relativeresource à TemplatedParent pour le textblock ca devrait marcher.

    A tester cyberbobby

  9. #9
    Membre confirmé Avatar de cyberbobby
    Inscrit en
    Février 2009
    Messages
    171
    Détails du profil
    Informations forums :
    Inscription : Février 2009
    Messages : 171
    Par défaut
    Hello !

    Bon voilà, j'ai essayé, lorsque je Binde ma Border, tout va bien mais lorsque j'essaie de binder ma TextBox sur le StackPanel, ca ne fonctionne pas et en utilisant {Binding RelativeSource={RelativeSource TemplatedParent}} ou {Binding DataContext, RelativeSource={RelativeSource TemplatedParent}} non plus.

    Donc, il me reste que la TextBox ou je change le DataContext sur l'événement Loaded. C'est dja plus propre mais j'aurais voulu binder les deux

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    <Border Style="{StaticResource BrdTemplate}" Visibility="{Binding Preferences.IsAPT, Converter={StaticResource ConverterDoubletoString}, ConverterParameter=preferences}">
        <TextBox DataContext="{Binding RelativeSource={RelativeSource TemplatedParent}}" Text="{Binding BudgetTon.Value,  Converter={StaticResource ConverterDoubletoString}, ConverterParameter=value}" Style="{StaticResource TBTemplate}"/>
    </Border>
    Donc voilà, déjà un grand merci pour votre aide ... Si vous pensez à autre chose, n'hésitez pas.

  10. #10
    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'ai reflechi à ton problème et pense avoir trouvé une solution élégante :

    Il faut créer un UserControl contenant ton Border et ton TextBox. Appelons le MonItem.

    Dans MonItem on crée deux propdp (Dependency property) qu'on appelle ItemDataContext, qui representera le DataContext de l'item et ListBoxDataContext qui representera le DataContext de la ListBox.

    On place ensuite dans l'ItemTemplate de ta ListBox (qu'on nomme MaListBox)
    Le UserControl MonItem en remplissant comme suit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    <ListBox.ItemTemplate>
        <DataTemplate>
     
    <MonItem ListBoxDataContext="{Binding DataContext,ElementName=MaListBox}" ItemDataContext="{Binding DataContext,RelativeSource={RelativeSource TemplatedParent}}">
        </MonItem>
    </DataTemplate>
    </ListBox.ItemTemplate>
    Ainsi le ListBoxDataContext de MonItem correspond à celui de la ListBox et ItemDataContext à celui de l'itemTemplate

    Pour la suite, dans le constructeur de MonItem, tu fais pointer le datacontext de LayoutRoot ( this.LayoutRoot.DataContext=this; ) vers lui même pour que les controls de MonItem puissent binder dessus.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
       <UserControl x:Name="MonUserControl" ... >
     
          <Border DataContext={Binding ListBoxDataContext}" Width="{Binding ListBoxWidth}">     
                <TextBox DataContext="{Binding ItemDataContext}" Text="{Binding ItemText}">
          </Border>
       </UserControl>
    Si tu veux plus de précision sur cette dernière partie tu peux te rendre sur cette page

Discussions similaires

  1. Récupérer fonction de la classe "parent" du "parent"
    Par langevert dans le forum Langage
    Réponses: 1
    Dernier message: 09/02/2009, 14h11
  2. Récupérer le nom du répertoire parent
    Par nicomax34 dans le forum Langage
    Réponses: 8
    Dernier message: 02/02/2009, 10h17
  3. Récupérer Font et Color du parent
    Par bubulemaster dans le forum Composants VCL
    Réponses: 1
    Dernier message: 27/02/2008, 17h22
  4. Récupérer les noms des classes parents
    Par see++ dans le forum Général Python
    Réponses: 2
    Dernier message: 12/03/2007, 17h35
  5. [TTreeView] Comment récupérer le nom d'un parent ?
    Par EssaiEncore dans le forum Composants VCL
    Réponses: 2
    Dernier message: 17/11/2005, 16h43

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