locked
observablecollection et listbox RRS feed

  • Question

  • Bonjour, j'ai une question qui va vous paraître basique.

    mais je n'arrive pas à lier ma listBox avec ObservableCollection.

    Si je fais :

    public class mycolor
            {
                public SolidColorBrush brush { get; set; }
            }

            public ObservableCollection<mycolor> collection = new ObservableCollection<mycolor>();

            private void BtColor_Click(object sender, RoutedEventArgs e)
            {
                SolidColorBrush scb = (Brush)rectangle.Fill as SolidColorBrush;
                collection.Add(new mycolor() { brush = scb });
                ListBoxColor.ItemsSource = collection;
            }

    alors l'ajout d'un rectangle de la couleur choisie se réalise bien. Mais je trouve pas ça très propre de mettre 

    ListBoxColor.ItemsSource = collection, à ce niveau là.

    J'ai essayé de procéder plutot comme ça (afin de passer par un binding, pour l'itemsource de ma listbox) :

    public class mycolor
    {
            public SolidColorBrush brush { get; set; }
    }

    public ObservableCollection<mycolor> collection { get; set; }

    private void BtColor_Click(object sender, RoutedEventArgs e)
    {
            SolidColorBrush scb = (Brush)rectangle.Fill as SolidColorBrush;
            collection.Add(new mycolor() { brush = scb });
    }

    xaml:

    <ListBox x:Name="ListBoxColor" ItemsSource="{Binding collection}" ItemsPanel="{StaticResource itemPanelColors}" ItemTemplate="{StaticResource dataColors}" />

    Mais l'évènement btColor_Click me soulève une erreur NullReferenceException.

    Si vous avez des conseils afin de bien lier mon itemsource à l'observableCollection.

    je vous remercie d'avance



    • Modifié RomainN mardi 24 avril 2012 11:20
    mardi 24 avril 2012 11:20

Réponses

  • @Romain : pour ton problème avec ton observablecollection, c'est tout simplement que tu n'as pas spécifié que le datacontext de ta vue était la vue elle-même :

    public MainPage()

    {

        this.DataContext =this;

    InitializeComponent(); }

    Après cela ton code devrait marcher


    S'il vous plaît n'oublier pas de marquer la ou les réponses qui aident à résoudre votre problème. Pour que la discussion puisse être marquée comme résolue

    • Marqué comme réponse RomainN mardi 24 avril 2012 13:20
    mardi 24 avril 2012 13:12
  • Le soucis viens de me "sauter à la figure" : dans ton premier exemple tu intialise ton observablecollection (= new ....), pas dans le second (avec DataContext), donc il est normal que ton champ "collection" soit vide. Il faut que dans ta propriété tu intialise cette liste.

    private ObservableCollection<mycolor> _collection;
    protected ObservableCollection<mycolor> Collection
    {
       get {
          if(_collection == null)
             _collection = new ObservableCollection<mycolor>();
          return _collection;
    }
    set {
       _collection = value;
    }

    Par contre c'est un peu du Q&D (j'aurai plus tendance à utiliser du MVVM pur pour ton cas) 

    Pour que la discussion puisse être identifiée comme résolue merci de marquer les réponses qui vous ont aidées à solutionner votre problème comme "réponse".

    • Marqué comme réponse RomainN mardi 24 avril 2012 14:58
    mardi 24 avril 2012 14:48

Toutes les réponses

  • Bonjour,

    Tu dois "attacher" le DataContext de ta page à ton VM pour que tu puisse binder.

    Exemple :

    public MainPage()
    {
       InitializeComponent();
    
       this.Loaded +=
          (object sender, EventArgs e) =>
          {
             this.DataContext = new TonVM();
          };
    }


    Pour que la discussion puisse être identifiée comme résolue merci de marquer les réponses qui vous ont aidées à solutionner votre problème comme "réponse".

    mardi 24 avril 2012 13:04
  • @Jerome :

    S'il est pas trop lourd, il faut mieux lier le datacontext dès la construction 

    public MainPage()

    {
       InitializeComponent();
    
       
             this.DataContext = new TonVM();
          
    }


    S'il vous plaît n'oublier pas de marquer la ou les réponses qui aident à résoudre votre problème. Pour que la discussion puisse être marquée comme résolue

    mardi 24 avril 2012 13:11
  • @Romain : pour ton problème avec ton observablecollection, c'est tout simplement que tu n'as pas spécifié que le datacontext de ta vue était la vue elle-même :

    public MainPage()

    {

        this.DataContext =this;

    InitializeComponent(); }

    Après cela ton code devrait marcher


    S'il vous plaît n'oublier pas de marquer la ou les réponses qui aident à résoudre votre problème. Pour que la discussion puisse être marquée comme résolue

    • Marqué comme réponse RomainN mardi 24 avril 2012 13:20
    mardi 24 avril 2012 13:12
  • Merci à vous deux pour vos réponses rapides.

    Même après avoir spécifié le DataContext, j'ai toujours la même erreur.

    Je met le code entier, peut être que mes classes ou propriétés ne sont pas au bon endroit.

    public partial class MainPage : PhoneApplicationPage
        {
            // Constructeur
            public MainPage()
            {
                this.DataContext = this;
                InitializeComponent();
            }
    
            public class mycolor
            {
                public SolidColorBrush brush { get; set; }
            }
    
            public ObservableCollection<mycolor> collection { get; set; }
    
            private void BtColor_Click(object sender, RoutedEventArgs e)
            {
                SolidColorBrush scb = (Brush)rectangle.Fill as SolidColorBrush;
                collection.Add(new mycolor() { brush = scb });
            }
    
      }


    • Modifié RomainN mardi 24 avril 2012 13:58
    mardi 24 avril 2012 13:57
  • Sur quelle ligne exactement as-tu l'exception "NullReferenceException" ?

    Pour que la discussion puisse être identifiée comme résolue merci de marquer les réponses qui vous ont aidées à solutionner votre problème comme "réponse".

    mardi 24 avril 2012 14:31
  • en faisant

    public MainPage()
            {
                this.DataContext = this;
                collection = new ObservableCollection<mycolor>();
                InitializeComponent();
            }

    ça marche...

    Du coup j'ai pas l'impression de gagner grand chose à faire cela, plutôt que

    public class mycolor
            {
                public SolidColorBrush brush { get; set; }
            }
    
            public ObservableCollection<mycolor> collection = new ObservableCollection<mycolor>();
    
            private void BtColor_Click(object sender, RoutedEventArgs e)
            {
                SolidColorBrush scb = (Brush)rectangle.Fill as SolidColorBrush;
                collection.Add(new mycolor() { brush = scb });
                ListBoxColor.ItemsSource = collection;
            }

    Si jamais vous avez un peu de temps à perdre pour m'expliquer la différence.

    Grand merci à vous deux de m'avoir aider.

    Cordialement Romain

     
    • Modifié RomainN mardi 24 avril 2012 14:38
    mardi 24 avril 2012 14:38
  • Bonjour Jérôme,

    sur:

    collection.Add(new mycolor() { brush = scb });

    mardi 24 avril 2012 14:42
  • Le soucis viens de me "sauter à la figure" : dans ton premier exemple tu intialise ton observablecollection (= new ....), pas dans le second (avec DataContext), donc il est normal que ton champ "collection" soit vide. Il faut que dans ta propriété tu intialise cette liste.

    private ObservableCollection<mycolor> _collection;
    protected ObservableCollection<mycolor> Collection
    {
       get {
          if(_collection == null)
             _collection = new ObservableCollection<mycolor>();
          return _collection;
    }
    set {
       _collection = value;
    }

    Par contre c'est un peu du Q&D (j'aurai plus tendance à utiliser du MVVM pur pour ton cas) 

    Pour que la discussion puisse être identifiée comme résolue merci de marquer les réponses qui vous ont aidées à solutionner votre problème comme "réponse".

    • Marqué comme réponse RomainN mardi 24 avril 2012 14:58
    mardi 24 avril 2012 14:48
  • Merci Jérôme, exactement ce que je voulais.

    Le MVVM, va falloir que je m'y attèle alors..


    • Modifié RomainN mardi 24 avril 2012 15:04
    mardi 24 avril 2012 15:03