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

Framework .NET Discussion :

[WPF] Problème de binding


Sujet :

Framework .NET

  1. #1
    Invité
    Invité(e)
    Par défaut [WPF] Problème de binding + validation
    Bonjour

    J'ai un problème de binding.

    En suivant un exemple j'ai commencé par :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    CRReportBO report = new CRReportBO();
    report.pTitle = "test";
    //...
     
    Binding bindingReport = new Binding();
    bindingReport.Source = report;
    bindingReport.Path = new PropertyPath("pTitle");
    re_title.SetBinding(TextBox.TextProperty, bindingReport);
    et dans mon XAML :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <TextBox Name="re_title"/>
    Jusque là, ça fonctionne.

    Puis j'ai vu qu'on pouvait faire cela plus simplement depuis le XAML.

    j'ai donc supprimé le code précédemment écrit, à l'exception de la déclaration de mon objet CRReportBO.

    et dans mon XAML j'ai mis :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <TextBox Name="re_title" Text="{Binding ElementName=report, Path=pTitle}" />
    Mais ça ne fonctionne pas. Qu'ai-je fait de faux ?
    Dernière modification par Invité ; 28/10/2007 à 15h40.

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

    Informations forums :
    Inscription : Octobre 2002
    Messages : 9 161
    Par défaut
    Il faut que tu déclares, dans les Resources, un ObjectDataProvider dans lequel tu mettras ton CRReportBO.

    Ou alors, il faut que tu définisses, dans le Load, que le DataContext de ta forme et que tu l'assignes à CRReportBO

  3. #3
    Invité
    Invité(e)
    Par défaut
    Ok, merci

    J'ai quelques chose qui s'affiche maintenant.

    Mais j'ai quelques questions.
    J'ai fait :

    XAML :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    <UserControl.Resources>
        <ObjectDataProvider x:Key="odpObservers" />
    </UserControl.Resources>
     
    ......
     
    <ComboBox Name="re_observer" DataContext="{Binding Source={StaticResource odpObservers}}" ItemsSource="{Binding}" DisplayMemberPath="pName" />
    C# :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    List<CRObserverBO> obs = CRObserversManager.pInstance.getObservers();
    ObjectDataProvider odpObservers = FindResource("odpObservers") as ObjectDataProvider;
    odpObservers.ObjectInstance = obs;
    Est-ce qu'il est possible de se passer des lignes 2 - 3 du code C# ci-dessus ? En modifiant le ObjectDataProvider du côté XAML par exemple. J'ai vu que ObjectDataProvider dispose d'une propriété ObjectInstance. J'ai essayer de m'en servir en lui donnant mon objet obs mais je dois mal avoir compris sont fonctionnement.

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

    Informations forums :
    Inscription : Octobre 2002
    Messages : 9 161
    Par défaut
    Oui, normalement, c'est possible comme ceci:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    <UserControl.Resources>
        <ObjectDataProvider x:Key="odpObservers" ObjectInstance={x:Type local:CRObserversManager}" />
    </UserControl.Resources>
    Maintenant, tu passes par un Singleton à priori donc il est fort possible que tu ais besoin également de MethodName

  5. #5
    Invité
    Invité(e)
    Par défaut
    Heu... je comprends plus du tout là.

    Je dois pas lui passer une instance de ma classe à ObjectInstance ?

    dans le cas d'un singleton (à propos, super ton article sur le développement en couches ), comment est-ce que l'odp fait pour récupérer l'instance de ma classe ?

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

    Informations forums :
    Inscription : Octobre 2002
    Messages : 9 161
    Par défaut
    Me suit trompé, c'est pas ObjectInstance, c'est ObjectType:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    <UserControl.Resources>
        <ObjectDataProvider x:Key="odpObservers" ObjectType={x:Type local:CRObserversManager}" />
    </UserControl.Resources>
    ObjectInstance, c'est lorsque tu veux faire référence à une instance d'un objet que tu as déjà instancié: typiquement, c'est un ObjectDataProvider qui fait appel à un autre ObjectDataProvider (via l'ObjectInstance)

  7. #7
    Invité
    Invité(e)
    Par défaut
    Ok, cette fois-ci je crois que j'ai compris.

    ObjectInstance, c'est lorsque tu veux faire référence à une instance d'un objet que tu as déjà instancié
    Donc un objet qui a déjà été ajouté aux ressources avec

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    ObjectDataProvider monODP = FindResource("monODP ") as ObjectDataProvider;
    odpReport.ObjectInstance = monInstance;

    Pendant que j'y suis, j'ai quelques problèmes avec la validation de mes champs.

    J'ai suivi ce tuto : http://paulstovell.net/Articles/WPFV...on.aspx#custom


    pour mes textBox, j'ai réussi.

    J'avais :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <TextBox Name="re_title" Text="{Binding Source={StaticResource odpReport}, Path=pTitle" />
    qui est devenu :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    <TextBox Name="re_title" Text="{Binding Source={StaticResource odpReport}, Path=pTitle, UpdateSourceTrigger=PropertyChanged}">
    	<Binding x:Name="re_titleBind" Source="{StaticResource odpReport}" Path="pTitle" UpdateSourceTrigger="PropertyChanged">
    		<Binding.ValidationRules>
    			<validators:CRRequiredValidationRule pErrorMessage="Le titre est obligatoire." />
    		</Binding.ValidationRules>
    	</Binding>
    </TextBox>
    ça fonctionne très bien.
    Juste une question : est-il possible de placer les ValidationRules directement dans la balise TextBox ?

    Mon problème maintenant : je tente de faire la même chose sur ma comboBox :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    <ComboBox Name="re_observer" 
    	ItemsSource="{Binding Source={StaticResource odpObservers}}" 
    	DisplayMemberPath="pName" 
    	/>
    mais je n'y arrive pas. J'ai tenté, comme pour le textBox, d'utiliser les balises Binding et Binding.ValidationRules mais sans succès.

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

    Informations forums :
    Inscription : Octobre 2002
    Messages : 9 161
    Par défaut
    Citation Envoyé par JuTs Voir le message
    Donc un objet qui a déjà été ajouté aux ressources avec

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    ObjectDataProvider monODP = FindResource("monODP ") as ObjectDataProvider;
    odpReport.ObjectInstance = monInstance;
    Oui

    Juste une question : est-il possible de placer les ValidationRules directement dans la balise TextBox ?
    C'est-à-dire ? Car les ValidationRules, c'est utilisé pour la validation, au moment du binding

    Mon problème maintenant : je tente de faire la même chose sur ma comboBox :
    Tu as essayé ceci:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    <ComboBox Name="re_observer" 
    	ItemsSource="{Binding Source={StaticResource odpObservers}}" 
    	DisplayMemberPath="pName" 
    	>
    <ComboBox.SelectedItem>
                <Binding ElementName="Selected" Path="Text">
                    <Binding.ValidationRules>
                        <local:ValidationRuleRange Min="10" Max="15" />
                    </Binding.ValidationRules>
                </Binding>
            </ComboBox.SelectedItem>
    </ComboBox>
    Avec le style suivant:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    <Style x:Key="ComboError" TargetType="{x:Type ComboBox}">
                <Style.Triggers>
                    <Trigger Property="Validation.HasError" Value="True">
                        <Setter Property="Background" Value="Red"/>
                        <Setter Property="Foreground" Value="White"/>
                    </Trigger>
                </Style.Triggers>
            </Style>
    Ici, si tu sélectionnes un élément qui n'est pas compris entre 10 et 15, le style en cas d'erreur (Fond Rouge/Couleur Blanche) est appliqué

    Bien sur, c'est à adapté à tes besoins car j'ignore ce que te renvois ton odpObservers

  9. #9
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par Thomas Lebrun Voir le message
    C'est-à-dire ? Car les ValidationRules, c'est utilisé pour la validation, au moment du binding
    Je me demandais s'il était possible de faire quelque chose du genre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <TextBox Text="{Binding ... , ici_les_param_pour_la_validation}">

    Citation Envoyé par Thomas Lebrun Voir le message
    Tu as essayé ceci:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    <ComboBox Name="re_observer" 
    	ItemsSource="{Binding Source={StaticResource odpObservers}}" 
    	DisplayMemberPath="pName" 
    	>
    <ComboBox.SelectedItem>
                <Binding ElementName="Selected" Path="Text">
                    <Binding.ValidationRules>
                        <local:ValidationRuleRange Min="10" Max="15" />
                    </Binding.ValidationRules>
                </Binding>
            </ComboBox.SelectedItem>
    </ComboBox>
    Avec le style suivant:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    <Style x:Key="ComboError" TargetType="{x:Type ComboBox}">
                <Style.Triggers>
                    <Trigger Property="Validation.HasError" Value="True">
                        <Setter Property="Background" Value="Red"/>
                        <Setter Property="Foreground" Value="White"/>
                    </Trigger>
                </Style.Triggers>
            </Style>
    Ici, si tu sélectionnes un élément qui n'est pas compris entre 10 et 15, le style en cas d'erreur (Fond Rouge/Couleur Blanche) est appliqué

    Bien sur, c'est à adapté à tes besoins car j'ignore ce que te renvois ton odpObservers
    ça n'a pas l'air de fonctionner. Apparemment il ne passe même pas dans la méthode de validation.

    mon comboBox est lié à une liste contenant des objets de type CRObserver (List<CRObserver>). Mon but est de m'assurer qu'un élément de la liste est sélectionné.

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

    Informations forums :
    Inscription : Octobre 2002
    Messages : 9 161
    Par défaut
    Citation Envoyé par JuTs Voir le message
    Je me demandais s'il était possible de faire quelque chose du genre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <TextBox Text="{Binding ... , ici_les_param_pour_la_validation}">
    Non, pas possible

    ça n'a pas l'air de fonctionner. Apparemment il ne passe même pas dans la méthode de validation.

    mon comboBox est lié à une liste contenant des objets de type CRObserver (List<CRObserver>). Mon but est de m'assurer qu'un élément de la liste est sélectionné.
    En créant ta propre ValidationRule utilisé pour vérifier si un élément est sélectionné, cela devrait marcher normalement

  11. #11
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par Thomas Lebrun Voir le message
    En créant ta propre ValidationRule utilisé pour vérifier si un élément est sélectionné, cela devrait marcher normalement
    C'est ce que j'ai fait, mais je passe même pas dans ma méthode de validation.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <Binding ElementName="Selected" Path="Text">
    Les valeurs des paramètres ElementName et Path, je dois les adapter ou c'est exactement celle-ci que je dois utiliser ?

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

    Informations forums :
    Inscription : Octobre 2002
    Messages : 9 161
    Par défaut
    Citation Envoyé par JuTs Voir le message
    Les valeurs des paramètres ElementName et Path, je dois les adapter ou c'est exactement celle-ci que je dois utiliser ?
    Tu peux garder ceux-ci normalement, étant donné que c'est pour ces ComboBoxItem. Dans le pire des cas, essaye Value pour le Path

  13. #13
    Invité
    Invité(e)
    Par défaut
    Ca ne va toujours pas

    Revoici mon code, peut-être ai-je fait une erreur ailleurs :

    XAML :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    <ComboBox Name="re_observer"
    	SelectionChanged="observer_SelectionChanged"
    	ItemsSource="{Binding Source={StaticResource odpObservers}, UpdateSourceTrigger=PropertyChanged}"
    	DisplayMemberPath="pName"
    	>
    	<ComboBox.SelectedItem>
    		<Binding ElementName="SelectedItem" Path="Text">
    			<Binding.ValidationRules>
    				<local:DumbValidationRule />
    			</Binding.ValidationRules>
    		</Binding>
    	</ComboBox.SelectedItem>
    </ComboBox>
    DumbValidationRule est une classe ValidationRule de test, sa méthode validate retourne false dans tous les cas (return new ValidationResult(false, null)

    odpObservers est un ObjectDataProvider définit de la manière suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    observers = CRObserversManager.pInstance.getObservers();
    ObjectDataProvider odpObservers = FindResource("odpObservers") as ObjectDataProvider;
    odpObservers.ObjectInstance = observers;
    en fichier joint, les variables après avoir sélectionné un élément de ma liste. Et d'après ce que je vois, je ne suis pas sûr que ce soit Path="Text" que je dois mettre. J'ai essayé avec Path="pName" mais ce n'est pas mieux



    Je trouve quand même étrange de ne pas trouver d'exemple de validation pour ce type de champ alors que pour les textBox il y en a des tonnes. Tu me dira que c'est le cas le plus simple à expliquer, mais bon...
    Images attachées Images attachées  

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

    Informations forums :
    Inscription : Octobre 2002
    Messages : 9 161
    Par défaut
    La propriété Path est appliqué à l'élément indiqué (ici, c'est SelectedItem). Si ton SelectedItem est d'un type particulier, il faut en effet indiquer une propriété de ce type.

    Tel que tu me le dit, en essayant avec pName, cela devrait marcher mais je testerais plsu en détails ce soir/demain pour être sur

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

    Informations forums :
    Inscription : Octobre 2002
    Messages : 9 161
    Par défaut
    Bon, je viens de faire le test avec un ComboBox bindée à une liste d'objet métier (ObservableCollection). J'ai créé ma propre ValidationRule et cela fonctionne sans problèmes et je pense savoir pourquoi cela ne marche pas chez toi.

    Essaye ce code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    <ComboBox Name="re_observer"
    	SelectionChanged="observer_SelectionChanged"
    	ItemsSource="{Binding Source={StaticResource odpObservers}, UpdateSourceTrigger=PropertyChanged}"
    	DisplayMemberPath="pName"
    	>
    	<ComboBox.SelectedItem>
    		<Binding Path="pName" UpdateSourceTrigger="PropertyChanged">
    			<Binding.ValidationRules>
    				<local:DumbValidationRule />
    			</Binding.ValidationRules>
    		</Binding>
    	</ComboBox.SelectedItem>
    </ComboBox>
    En gros, dans ton binding du SelectedItem, tu renseignais la proprité ElementName. Or cette propriété est utilisé lorsque l'on veut faire du binding sur un autre élément alors que toi, tu le fait sur l'élément courant (SelectedItem)


    Test et tiens moi au courant

  16. #16
    Invité
    Invité(e)
    Par défaut
    Ca ne vas pas.

    Est-ce que le problème ne provenir du type de liste ? Tu dis utiliser des ObservableCollection. Or de mon côté j'ai utilisé une bête liste générique (List<T>).

    J'ai tenté de changer ma List en ObservableCollection mais impossible de le faire (The type or namespace name 'ObservableCollection' could not be found). Ce type se trouve bien dans le namespace System.Collections.ObjectModel ?


    Autre chose, sur la ligne

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <local:DumbValidationRule />
    j'ai le warning suivant :

    Warning 3 The element 'Binding.ValidationRules' in namespace 'http://schemas.microsoft.com/winfx/2006/xaml/presentation' has invalid child element 'DumbValidationRule' in namespace 'clr-namespace:CROA.TOOLS.Validators;assembly=CROA.TOOLS'. List of possible elements expected: 'sgValidationRule, ExceptionValidationRule' in namespace 'http://schemas.microsoft.com/winfx/2006/xaml/presentation'. E:\TD\CROA\CROA.GUI\Controls\CRNewReportControl.xaml 49 10 CROA.GUI

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

    Informations forums :
    Inscription : Octobre 2002
    Messages : 9 161
    Par défaut
    C'est pas 'ObservableCollection', c'est 'ObservableCollection<T>'

    Sinon, tu peux garder ta liste et implémenter INotifyPropertyChanged (c'est ce que fait en fait 'ObservableCollection')

    Pour les warnings, je pense que tu peux les ignorer pour le moment

  18. #18
    Invité
    Invité(e)
    Par défaut
    J'ai réussi !

    Bon, j'ai pas trouvé comment tout seul . Entre-temps j'avais envoyer un e-mail à Paul Stovell, auteur de l'article que j'ai lu pour mes premières validations.

    Voici sa réponse :

    I'd say you're pretty close to the solution; the problem lays with the Binding for the SelectedItem. What you'll need to do is assign the SelectedItem to somewhere for the binding to work correctly.



    For example, in code behind you might have:



    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    private object _selectedObserver;
     
    public object SelectedObserver { get { return _selectedObserver; } set { _selectedObserver = value; } }


    Then in your XAML:



    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    <Window
        x:Name="_this"
     
        .....
     
        >


    And then your ComboBox:



    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    <ComboBox Name="re_observer"
            ItemsSource="{Binding Source={StaticResource odpObservers}, UpdateSourceTrigger=PropertyChanged}"
            DisplayMemberPath="pName"
            >
            <ComboBox.SelectedItem>
                    <Binding ElementName="_this" Path="SelectedObserver">
                            < Binding.ValidationRules>
                                    <local:MyValidationRule />
                            </Binding.ValidationRules>
                    </Binding>
            </ComboBox.SelectedItem>
    </ComboBox>


    This makes the Binding used on your ComboBox valid, which then allows the validation rule to kick in.

    ça à l'air de fonctionner. En tout cas je passe dans ma méthode de validation. Encore une ou deux vérifications et je pense que je pourrai, enfin, cliquer sur

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

    Informations forums :
    Inscription : Octobre 2002
    Messages : 9 161
    Par défaut
    Etrange, je n'ai pas besoin de faire cela pour que cela fonctionne chez moi... Mais p-e parce que je suis sous VS 2008 Beta 2....

    Content de voir que tu t'en sors !


    A+

  20. #20
    Invité
    Invité(e)
    Par défaut
    Est-ce que tu pourrais m'envoyer le programme test que tu as fait ? histoire de voir si chez moi il fonctionne. J'utilise Visual Studio 2005

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

Discussions similaires

  1. [WPF] Problème de binding avec une classe perso
    Par Invité dans le forum Windows Presentation Foundation
    Réponses: 5
    Dernier message: 12/04/2010, 18h45
  2. Réponses: 0
    Dernier message: 30/06/2009, 21h41
  3. [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
  4. [WPF] Problème de binding
    Par tomlev dans le forum Windows Presentation Foundation
    Réponses: 3
    Dernier message: 04/02/2008, 14h08
  5. [WPF] Problème de binding entre une SortedList et une ListBox
    Par Invité dans le forum Général Dotnet
    Réponses: 4
    Dernier message: 10/12/2007, 13h20

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