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 :

Binding vers un contrôle d'une autre classe


Sujet :

Silverlight

  1. #1
    Membre habitué
    Profil pro
    Inscrit en
    Août 2010
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Août 2010
    Messages : 11
    Par défaut Binding vers un contrôle d'une autre classe
    Bonjour à tous,

    ma question peut paraître bête mais la voici :

    Je cherche à pouvoir récupérer la valeur selectionnée d'une combo qui se trouve dans une autre classe.

    Je m'explique, j'ai dans mon application, une classe permettant de choisir la base de données sur laquelle se connecter. Ce choix se présente sous forme d'une combobox.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    <Grid x:Name="LayoutRoot" Style="{StaticResource CustomerGridStyle}">
            <ComboBox Height="18" HorizontalAlignment="Left" Margin="0,1,0,0" Name="cbCustomer" VerticalAlignment="Top" Width="200" Loaded="cbCustomer_Loaded"  />
            <Button Content="OK" Height="18" HorizontalAlignment="Left" Margin="205,1,0,0" Name="btnOK" VerticalAlignment="Top" Width="30" />
        </Grid>
    Et dans une autre classe, j'essaie d'accéder à la valeur choisie dans cette combo pour moi passer cette valeur en question en paramètre à une de mes méthodes. J'essaie donc de faire ceci mais je vois bien que ce n'est pas ça...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <riaControls:Parameter ParameterName="dbName" Value="{Binding ElementName=DBName, Path=cbCustomer.SelectedItem}" />
    Faut-il indiquer quelque part le nom de la classe en question? Mais comment? Bref, je ne sais pas trop comment faire.
    Pourriez-vous me donner un coup de main?

    Merci d'avance.

  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 : 52
    Localisation : France

    Informations professionnelles :
    Activité : Expert .NET

    Informations forums :
    Inscription : Février 2010
    Messages : 1 504
    Par défaut
    Bonjour,

    La combobox et le control Parameter se trouve dans le même usercontrol ?

    si oui tu peux faire quelquechose comme ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <riaControls:Parameter ParameterName="dbName" Value="{Binding ElementName=cbCustomer, Path=SelectedItem}" />
    si non, tu devrais passer par une classe commune héritant de INotifyPropertyChanged afin de notifier à l'interface utilisateur que quelque chose vient de changer et de le prendre en compte via le binding.

    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
     
    public class DataViewModel : INotifyPropertyChanged
    {
      public object SelectedItem
      {
          get
          {
                return _selectedItem;
          }
     
          set
          {
               if( _selectedItem != value )
               {
                    _selectedItem = value;
                   this.RaisePropertyChanged("SelectedItem");
               }
          }
      }
     
      private object _selectedItem = null; 
    }
    dans les loads des controles contenant la combobox et Parameter

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    ...
    public void Loaded(...)
    {
         this.LayoutRoot.DataContext = this;
    }
    ...
    propdp DataViewModel (propertyDependency)
    ...
    ensuite pour la ComboBox :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    <ComboBox Height="18" HorizontalAlignment="Left" Margin="0,1,0,0" Name="cbCustomer" VerticalAlignment="Top" Width="200" Loaded="cbCustomer_Loaded" SelectedItem="{Binding DataViewModel.SelectedItem, Mode=TwoWay}"  />
    et enfin le control Parameter :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <riaControls:Parameter ParameterName="dbName" Value="{Binding DataViewModel.SelectedItem}" />
    Pour cette deuxieme solution, plus complexe, on entre dans le pattern MVVM

  3. #3
    Membre habitué
    Profil pro
    Inscrit en
    Août 2010
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Août 2010
    Messages : 11
    Par défaut
    Merci pour ta réponse rapide.

    J'ai essayé d'appliquer ce que tu as dit mais n'y arrive pas

    Pour la nouvelle classe DataViewModel j'obtiens une erreur. Il ne reconnait pas le RaisePropertyChanged
    Error 'DataViewModel' does not contain a definition for 'RaisePropertyChanged' and no extension method 'RaisePropertyChanged' accepting a first argument of type 'DataViewModel' could be found (are you missing a using directive or an assembly reference?)
    Et ensuite j'avoue que je ne comprends pas trop ce que tu voudrais que je fasse avec ceci...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    propdp DataViewModel (propertyDependency)
    J'ai cru comprendre avec la documentation que je devais faire plus ou moins quelque chose comme ça

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    public int MyProperty
            {
                get { return (int)GetValue(MyPropertyProperty); }
                set { SetValue(MyPropertyProperty, value); }
            }
     
            public static readonly DependencyProperty MyPropertyProperty =
                    DependencyProperty.Register("MyProperty", typeof(int), typeof(MyType), new PropertyMetada(true));
            }
    Mais je ne comprends pas trop... Là il me souligne "MyType" et PropertyMetaData.
    Je ne comprends pas trop quoi mettre à la place et si c'est bien quelque chose ainsi que je dois faire

    Merci encore et désolée pour ma non connaissance...

  4. #4
    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 : 52
    Localisation : France

    Informations professionnelles :
    Activité : Expert .NET

    Informations forums :
    Inscription : Février 2010
    Messages : 1 504
    Par défaut
    Commence par regarder ce tuto de Benjamin Broux qui explique très bien les différents principes de Binding dans SL :

    http://broux.developpez.com/articles...g-silverlight/

  5. #5
    Membre habitué
    Profil pro
    Inscrit en
    Août 2010
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Août 2010
    Messages : 11
    Par défaut
    Voilà, j'ai lu tout le tuto. Et suite à cela, voici mes modifications.

    Plus d'erreur dans ma classe DataViewModel. La voilà au complet:

    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
    using System;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Ink;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
    using System.ComponentModel;
     
    namespace CRMobile.AdminTools.Views
    {
        public class DataViewModel : INotifyPropertyChanged
        {
            public event PropertyChangedEventHandler PropertyChanged;
     
            private object _selectedItem = null;
     
            public object SelectedItem
            {
                get
                {
                    return _selectedItem;
                }
     
                set
                {
                    if (_selectedItem != value)
                    {
                        _selectedItem = value;
                        this.RaisePropertyChanged("SelectedItem");
                    }
                }
            }
     
            #region RaisePropertyChanged Members
     
            public void RaisePropertyChanged(string propertyName)
            {
                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
                }
     
            }
     
            #endregion
        }
    }
    Et voici ce que j'ai ajouté au niveau de ma classe CustomerCombobox:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    public static readonly DependencyProperty ValeurProperty; 
     
            static CustomerCombobox()
            {
                //1er paramètre : nom de la propriété qui pourra être utilisé en XAML
                //Paramètres 2 et 3 : Indique que chaque objet de type CustomerComboBox(param3) aura une propriété de type object (param2)
                ValeurProperty = DependencyProperty.Register("DataViewModel.SelectedItem", typeof(object), typeof(CustomerCombobox), new PropertyMetadata(true));
                //ValeurProperty : Clef qui permet de référencer cette propriété depuis le code, quand on veut faire une opération sur cette propriété.
            }
    Mais pas de chance, ça ne fonctionne toujours pas. J'ai mis des BreakPoints un peu partout, entre autre dans ma classe DataViewModel, mais jamais ils ne sont atteints.

    Merci encore.

  6. #6
    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 : 52
    Localisation : France

    Informations professionnelles :
    Activité : Expert .NET

    Informations forums :
    Inscription : Février 2010
    Messages : 1 504
    Par défaut
    1°) ta DataViewModel est bien construite
    2°) montre nous le Binding que tu emploies sur ta ComboBox

  7. #7
    Membre habitué
    Profil pro
    Inscrit en
    Août 2010
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Août 2010
    Messages : 11
    Par défaut
    Merci pour le point 1
    Pour le point 2 j'ai mis comme tu m'avais indiqué en fait :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     <ComboBox Height="18" HorizontalAlignment="Left" Margin="0,1,0,0" Name="cbCustomer" VerticalAlignment="Top" Width="200" Loaded="cbCustomer_Loaded" SelectedItem="{Binding DataViewModel.SelectedItem, Mode=TwoWay}"  />

  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 : 52
    Localisation : France

    Informations professionnelles :
    Activité : Expert .NET

    Informations forums :
    Inscription : Février 2010
    Messages : 1 504
    Par défaut
    très bien. Tu peux laisser tomber la propdp CustomerCombobox car tu utilises le ViewModel.

    Tu peux la remplacer par une propdp DataViewModel par exemple sans oublier dans le constructeur le :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    this.LayoutRoot.DataContext = this;
    qui permet de faire l'utilisation des les propriétés de ton UserControl sous forme de Binding (voir le Binding de DataViewModel.SelectedItem).
    Il est important aussi que ton DataViewModel soit instancier (sans doute à l'exterieur de ton UserControl)

    Il y a d'autre moyen de faire, je t'ai donné une solution simple

  9. #9
    Membre habitué
    Profil pro
    Inscrit en
    Août 2010
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Août 2010
    Messages : 11
    Par défaut
    Oulala que je m'embrouille

    Vu qu'il faut rajouter ceci
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    this.LayoutRoot.DataContext = this;
    à la classe DataViewModel j'ai supprimé la classe et en ai recréé une de type page Silverlight. Autrement il ne me reconnaissait pas le LayoutRoot.

    Ma classe ressemble donc maintenant à ceci (avec la nouvelle propdp)

    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
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
    using System.Windows.Navigation;
    using System.ComponentModel;
     
    namespace CRMobile.AdminTools.Views
    {
        public partial class DataViewModel : INotifyPropertyChanged
        {
            public event PropertyChangedEventHandler PropertyChanged;
            public static readonly DependencyProperty ValeurProperty;
     
            public DataViewModel()
            {
                InitializeComponent();
                this.LayoutRoot.DataContext = this;
            }
     
            static DataViewModel()
            {
                //1er paramètre : nom de la propriété qui pourra être utilisé en XAML
                //Paramètres 2 et 3 : Indique que chaque objet de type DataViewModel(param3) aura une propriété de type object (param2)
                ValeurProperty = DependencyProperty.Register("DataViewModel.SelectedItem", typeof(object), typeof(DataViewModel), new PropertyMetadata(true));
                //ValeurProperty : Clef qui permet de référencer cette propriété depuis le code, quand on veut faire une opération sur cette propriété.
            }
     
            private object _selectedItem = null;
     
            public object SelectedItem
            {
                get
                {
                    return _selectedItem;
                }
     
                set
                {
                    if (_selectedItem != value)
                    {
                        _selectedItem = value;
                        this.RaisePropertyChanged("SelectedItem");
                    }
                }
            }
     
            #region RaisePropertyChanged Members
     
            public void RaisePropertyChanged(string propertyName)
            {
                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
                }
     
            }
     
            #endregion
        }
    }
    Pour l'instanciation de ma classe DataViewModel, je pensais faire ça quand je clique sur le bouton 'OK' après avoir sélectionné un élément de ma combo. Cette évènement (du click sur OK) se trouve dans la classe MainPage. C'est dans cette même classe qu'est instancié la classe CustomerCombobox qui contient les fameux contrôles combobox ainsi que le bouton 'ok'.

    Voici la méthode:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    void Button_Click(object sender, RoutedEventArgs e)
            {
                DataViewModel _dataViewModel = new DataViewModel();
     
                DBName = ((Web.Models.Customer)_customerCbox.ListControl.SelectedItem).DBName;
                ServerName = ((Web.Models.Customer)_customerCbox.ListControl.SelectedItem).ServerName;
     
            }
    Mais je suppose que je dois faire quelque chose avec le 'dataViewModel ' ensuite?
    Aussi, quand je suis en mode Debug, que dans l'immediate je tape : ?_dataViewModel voici ce que j'obtiens:
    ?_dataViewModel
    _contentLoaded: true
    _selectedItem: null
    LayoutRoot: {System.Windows.Controls.Grid}
    PropertyChanged: null
    SelectedItem: null
    Alors que j'ai l'impression que je dois avoir n'importe quelle valeur mais pas NULL.

    J'espère ne pas trop t'ennuyer avec ces questions peut-être idiotes?...

  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 : 52
    Localisation : France

    Informations professionnelles :
    Activité : Expert .NET

    Informations forums :
    Inscription : Février 2010
    Messages : 1 504
    Par défaut
    Effectivement tu t'embrouilles un peu

    Il faut garder ta classe DataViewModel comme elle est. Ce n'est pas un UserControl. C'est cette classe qui sera commune à l'ensemble de tes controles.

    On va laisser tomber la propdp pour le moment et le DataContext de LayoutRoot, car je sens que cela t'embrouille pas mal et utiliser une autre solution plus simple.

    Vu que DataViewModel doit être global tu peux faire ceci dans les ressources de App.xaml (ressource de l'application)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    <my:DataViewModel x:Key="DataViewModel"/>
    DataViewModel est désormais accessible de partout.

    si tu veux l'utiliser dans ta ComboBox par exemple :

    <ComboBox Height="18" HorizontalAlignment="Left" Margin="0,1,0,0" Name="cbCustomer" VerticalAlignment="Top" Width="200" Loaded="cbCustomer_Loaded" SelectedItem="{Binding Source={StaticResource DataViewModel},Path=SelectedItem, Mode=TwoWay}" />
    Note que je définie la Source qui va regarder dans les Ressources disponibles et notamment dans les ressources global de App.

    J'espère que c'est plus clair

  11. #11
    Membre habitué
    Profil pro
    Inscrit en
    Août 2010
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Août 2010
    Messages : 11
    Par défaut
    Merci c'est plus clair en effet ,
    Je viens de tout appliquer, j'ai donc maintenant ma classe DataViewModel à avant (Quand tu m'as dis qu'elle était correcte), j'ai ajouté la classe à App.xaml, modifié le binding de la combo. Tout build bien.

    Mais malheureusement, mes paramètres ne sont toujours pas passés.
    Te faut-il plus de renseignements encore? Les bindings de mes paramètres doivent-il changer aussi?
    Actuellement ils valent ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    <riaControls:Parameter ParameterName="dbName" Value="{Binding DataViewModel.SelectedItem}" />
                    <riaControls:Parameter ParameterName="serverName" Value="{Binding DataViewModel.SelectedItem}" />

  12. #12
    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 : 52
    Localisation : France

    Informations professionnelles :
    Activité : Expert .NET

    Informations forums :
    Inscription : Février 2010
    Messages : 1 504
    Par défaut
    Tout les Binding qui nécessite le DataViewModel fonctionne de la manière que je t'ai montré dans mon dernier message pour la ComboBox.

    donc pour tes controles paramètres c'est la même chose :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    <riaControls:Parameter ParameterName="dbName" Value="{Binding Source={StaticResource DataViewModel},Path=SelectedItem}" />
                    <riaControls:Parameter ParameterName="serverName" Value="{Binding Source={StaticResource DataViewModel},Path=SelectedItem }"/>

  13. #13
    Membre habitué
    Profil pro
    Inscrit en
    Août 2010
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Août 2010
    Messages : 11
    Par défaut

    Un giga grand merci!! ça fontionne!
    J'ai du seulement apporter une autre modif pour les paramètres, j'ai du mettre les .DBName et .ServerName comme ci dessous:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    <riaControls:Parameter ParameterName="dbName" Value="{Binding Source={StaticResource DataViewModel},Path=SelectedItem.DBName}" />
    <riaControls:Parameter ParameterName="serverName" Value="{Binding Source={StaticResource DataViewModel},Path=SelectedItem.ServerName }"/>
    Encore un tout grand merci pour avoir passé du temps avec moi sur la question

  14. #14
    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 : 52
    Localisation : France

    Informations professionnelles :
    Activité : Expert .NET

    Informations forums :
    Inscription : Février 2010
    Messages : 1 504
    Par défaut
    Pas de problème L'important c'est de progresser.

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

Discussions similaires

  1. Réponses: 0
    Dernier message: 26/05/2015, 15h52
  2. Réponses: 0
    Dernier message: 31/05/2010, 14h55
  3. Garder une référence vers une variable d'une autre classe
    Par choupeo dans le forum Windows Forms
    Réponses: 5
    Dernier message: 08/12/2007, 18h30
  4. Contrôle d'une fenêtre par une autre classe
    Par SuperWeight dans le forum Windows
    Réponses: 4
    Dernier message: 19/04/2007, 16h01
  5. Réponses: 5
    Dernier message: 09/03/2007, 10h07

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