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 :

Erreur avec binding: cast d'un objet de type MS.Internal.NamedObject


Sujet :

Windows Presentation Foundation

  1. #1
    Membre du Club Avatar de Takumi
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Juin 2009
    Messages
    163
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Juin 2009
    Messages : 163
    Points : 62
    Points
    62
    Par défaut Erreur avec binding: cast d'un objet de type MS.Internal.NamedObject
    Bonsoir,

    J'avance doucement mais surement dans mon application en suivant le pattern MVVM, et je suis tombé sur un problème avec un binding. J'ai dans mon application un UserControl qui contient une listbox qui a comme ItemSource une ObservableCollection<Playlist> (playlist est ici une classe que j'ai crée).

    J'ai voulus par la suite binder la propriété SelectedItem de la listbox à une propriété du view-model associé au UserControl contenant la listbox. Mon problème intervient quand je veux tester, je souhaite sélectionner un élément de la listbox et là mon application plante avec l'erreur suivante:

    Impossible d'effectuer un cast d'un objet de type 'MS.Internal.NamedObject' en type 'PlayerOne.Models.Playlist'.
    L'erreur est signalé sur la fonction surchargé equals de mon objet de type Playlist:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    public override bool Equals(object obj)
    {
        return this._Title.ToLower() == (((Playlist)obj).Title).ToLower();
    }
    Je ne vois pas comment résoudre ce problème.

    je vous remercie grandement d'avance pour votre aide.

  2. #2
    Membre averti

    Profil pro
    Inscrit en
    Septembre 2005
    Messages
    214
    Détails du profil
    Informations personnelles :
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 214
    Points : 341
    Points
    341
    Par défaut
    A première vue (mais je prends pas trop de risque en écrivant ça...) ton binding ne fonctionne pas...

    Est-ce que tu peux nous donner soit une appli de démo qui reproduit le problème soit le XAML où est présent le binding ?

  3. #3
    Membre du Club Avatar de Takumi
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Juin 2009
    Messages
    163
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Juin 2009
    Messages : 163
    Points : 62
    Points
    62
    Par défaut
    Le XAML où se trouve le binding ressemble à ça:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    <UserControl x:Class="PlayerOne.Views.AllPlaylistsView"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
                 xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
                 xmlns:diagnostics="clr-namespace:System.Diagnostics;assembly=WindowsBase"
                 mc:Ignorable="d" 
                 d:DesignHeight="300" d:DesignWidth="300">
        <Grid>
            <ListBox ItemsSource="{Binding Path=AllPlaylist}"
                     SelectedItem="{Binding Path=CurrentPlaylist, diagnostics:PresentationTraceSources.TraceLevel=High}" />
        </Grid>
    </UserControl>
    C'est le code d'une des mes view et quoi qu'il en soit elle est bien bindé à son view-model, car le binding de la propriété ItemsSource fonctionne bien, je vois la ListBox remplis. Je met pas le code C# de l'accesseur sur lequel le binding, c'est un simple get et set en une ligne, je pense pas que le problème soit là.

  4. #4
    Membre expert
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    2 210
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 2 210
    Points : 3 015
    Points
    3 015
    Par défaut
    Personnelement, j'ai pris l'habitude d'utiliser une CollectionViewSource dans le ViewModel. En affectant la propriété CurrentItem de la CollectionViewSource dans le ViewModel, la sélection se fait dans la liste et vis versa.

    Il donne aussi l'avantage de filtrer, trier et regrouper les données facilement :

  5. #5
    Membre averti

    Profil pro
    Inscrit en
    Septembre 2005
    Messages
    214
    Détails du profil
    Informations personnelles :
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 214
    Points : 341
    Points
    341
    Par défaut
    Je vois pas trop d'où ça peut venir alors...

    Comme l'a dit binno, utiliser CollectionViewSource est également un bon moyen de faire.

    Est-ce que tu peux nous passer une appli qui reproduit le problème ?

  6. #6
    Membre du Club Avatar de Takumi
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Juin 2009
    Messages
    163
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Juin 2009
    Messages : 163
    Points : 62
    Points
    62
    Par défaut
    Bonsoir,

    Je met en pièce jointes mon projet complet. Si tu veux reproduire l'erreur c'est pas compliqué. Tu compiles, tu verras sur la gauche de l'interface une listbox avec 2 items dedans et un bouton en dessous de la listbox. Il te suffit juste de cliquer sur un des 2 items. Ensuite si tu veux voir le code xaml associé à cette vue, il s'agit du fichier qui se nomme AllPlaylistView.xaml (et pour le view-model c'est le même nom avec ViewModel à la fin). L'interface est un peu vide, mais j'ai pas repris encore tous les style et UserControl que j'avais de la précédente version de mon appli quand elle était pas encore faite en MVVM. Là je me contente déjà de bien comprendre le concept et tester voir comment fonctionne tel ou tel truc.

    Pour l'histoire de la CollectionViewSource, j'ai rapidement jeté un coup d'oeil et essayé. Je ne sais pas si c'était la bonne façon de faire. Mais même avec j'ai toujours eu le problème. J'ai du louper un truc.

  7. #7
    Membre averti

    Profil pro
    Inscrit en
    Septembre 2005
    Messages
    214
    Détails du profil
    Informations personnelles :
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 214
    Points : 341
    Points
    341
    Par défaut
    Bon visiblement le problème vient de l'implémentation que tu as fais de la méthode Equals. En général, dans cette implémentation on vérifie que le type est le bon avant de faire le cast. Ta méthode devient donc:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    public override bool Equals(object obj)
    {
        if (obj as Playlist == null) return false;
     
        return this._Title.ToLower() == (((Playlist)obj).Title).ToLower();
    }
    Dans ce cas plus de problème de crash.

    Sni

  8. #8
    Membre du Club Avatar de Takumi
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Juin 2009
    Messages
    163
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Juin 2009
    Messages : 163
    Points : 62
    Points
    62
    Par défaut
    Bonsoir,

    J'ai donc corrigé le problème avec la méthode equals de la manière suivante:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    public override bool Equals(object obj)
    {
        Playlist PlaylistObj = obj as Playlist;
     
        if ((object)PlaylistObj != null)
            return this == PlaylistObj;
        else
            return false;
    }
    Et voila la surcharge de == :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    public static bool operator ==(Playlist P1, Playlist P2)
    {
         if (ReferenceEquals(P1, P2))
            return true;
         else if( ((object)P1 == null) || ((object)P2 == null) )
            return false;
         else
            return P1.Title.ToLower() == P2.Title.ToLower();
    }
    Est-ce que cela te semble correct?

    Sinon j'ai aussi essayé d'utiliser une CollectionViewSource dans mon view-model. Cela marche plutôt bien, par contre j'avais besoin de déclencher la notification (avec INotifyPropertyChanged) comme quoi un de mes accesseur de mon view-model a changé lorsqu'un le CurrentItem de la CollectionViewSource change. Cette accesseur qui doit être notifié comme changé renvois un view-model sur lequel mon interface est bindé. Ma propriété est la suivante:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    public PlaylistDetailViewModel CurrentPlaylistDetail
    {
        get 
        {
           if ((Playlist)this._AllPlaylistView.View.CurrentItem != null)
               return new PlaylistDetailViewModel((Playlist)this._AllPlaylistView.View.CurrentItem);
           else
               return null;
        }
    }
    Ensuite afin de savoir quand le CurrentItem a changé et donc notifié le changement de valeur pour mon accesseur, j'ai écrit ceci dans le constructeur de mon view-model:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    public AllPlaylistsViewModel(ObservableCollection<Playlist> Playlists)
    {
        this._AllPlaylist = Playlists;
        this._AllPlaylistView = new CollectionViewSource();
        this._AllPlaylistView.Source = this._AllPlaylist;
        this._AllPlaylistView.View.CurrentChanged += delegate { this.OnPropertyChanged("CurrentPlaylistDetail"); };
    }
    Je voulais savoir si cela était correct.

  9. #9
    Membre du Club Avatar de Takumi
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Juin 2009
    Messages
    163
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Juin 2009
    Messages : 163
    Points : 62
    Points
    62
    Par défaut
    Bonjour,

    Je m'excuse de remonter cette discussion mais j'ai peur qu'elle ne tombe dans le néant de la base de donnée qui la sauvegarde. Je voudrais juste savoir si ce que j'ai fait et présenté précédemment concernant la CollectionViewSource est correct. Savoir si il y a une grosse erreur que je n'aurais pas du faire ou bien si c'est à peu près correct. Si il manque du code pour en juger je peux mettre mon projet.

    Merci d'avance.

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

Discussions similaires

  1. Réponses: 7
    Dernier message: 26/04/2011, 18h00
  2. Réponses: 0
    Dernier message: 13/03/2010, 10h25
  3. ClassCastException avec un EJB renvoyant un objet de type particulier
    Par vsevel dans le forum Glassfish et Payara
    Réponses: 1
    Dernier message: 20/06/2007, 13h01
  4. Réponses: 2
    Dernier message: 06/03/2007, 19h38
  5. socket : erreur avec bind()
    Par horkets dans le forum Réseau
    Réponses: 11
    Dernier message: 30/10/2006, 11h47

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