Binding listbox with MVVM Windows Phone

Hi i'm new using MVVM and i'm trying to binding a listbox but it doesn't work. Here's my code

Model

   public class Musicmodel : INotifyPropertyChanged
   {
    //variables privadas

      private String _artista;
      private Uri _href;
      private String _informacion;
      private Double _Dvalue;

    public String artista
    {
        get
         {
            return this._artista;  
          }
        set
        {
            this._artista= value;

            this.RaisePropertyChanged("artista");
        }
    }

    public Uri href { 
        get {

            return this._href;
         }

        set
        {
            this._href = value;
            this.RaisePropertyChanged("href");
        }

    }
    public String informacion {
        get 
        {
            return this._informacion;
        }

        set
        {
            this._informacion = value;
            this.RaisePropertyChanged("informacion");
        }
    }
    public Double Dvalue
    {
        get
        {
            return this._Dvalue;
        }
        set
        {
            this._Dvalue = value;
            this.RaisePropertyChanged("Dvalue");
        }

    }



    public event PropertyChangedEventHandler PropertyChanged;

    private void RaisePropertyChanged(string propertyName)
    {
        if (this.PropertyChanged != null)
        {
            this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
   }
  }

ViewModel

public class DownloadFileViewModel : INotifyPropertyChanged
{

    private WebClient clienteDownload;


    private ObservableCollection<Model.Music>_musicSource= new ObservableCollection<Model.Music>();

    public ObservableCollection<Model.Music> musicSource
    {
        get
        {
            return this._musicSource;
        }
        set
        {
            this._musicSource = value;
            RaisePropertyChanged("musicSource");
        }
    }


    private int index = 0;


    //request para descargar la canción
    public void request(Model.Musicmodel item)
    {
        this.clienteDownload = new WebClient();
        this.clienteDownload.DownloadProgressChanged += new DownloadProgressChangedEventHandler(clienteDownload_DownloadProgressChanged);

        //agregamos el item al music
        this.musicSource.Add(item);

        this.clienteDownload.OpenReadAsync(this.musicSource[index].href);

    }


    private void clienteDownload_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
    {
       this.musicSource[index].Dvalue=(double)e.ProgressPercentage;

    }


    public event PropertyChangedEventHandler PropertyChanged;

    private void RaisePropertyChanged(string propertyName)
    {
        if (this.PropertyChanged != null)
        {
            this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }


  }
  }

View

            <ListBox x:Name="list" ItemsSource="{Binding musicSource}">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Vertical">
                        <TextBlock Text="{Binding artista}"/>
                        <ProgressBar Value="{Binding Dvalue}"/>
                    </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>

Code Behind

          protected override void OnNavigatedTo(NavigationEventArgs e)
          {

            DownloadFileViewModel download = new DownloadFileViewModel();
            Model.Music newMusic = new Model.Music() { href = new   Uri("http://media1.li.ru/b/4/mp3/2/95366/953662_14Friday_Im_In_Love.mp3", UriKind.Absolute), artista = "the cure" };
            download.request(newMusic);
            this.DataContext = download;
            base.OnNavigatedTo(e);

         }

I've debuged this and the download works fine and my ObservableCollection fills correctly whithout any problem but when i try to binding my listbox fails. please what do i'm doing wrong? thanks

Upvotes: 0

Views: 790

Answers (2)

Ivan Crojach Karačić
Ivan Crojach Karačić

Reputation: 1911

The problem is quite simple. You initialize your musicSource property at the begining in

private ObservableCollection<Model.Music>_musicSource= new ObservableCollection<Model.Music>();

And then just add stuff to it after the request completes. The RaiseProperyChanged("Property") will only fire when you add a new observable collection but not when you add items to it.

Add this line again to the end of the request (when you populate your musicSource)

RaisePropertyChanged("musicSource");

This will trigger another update in the view

EDIT:

Another approach is to have an additional field like

private ObservableCollection<Model.Music>_anotherMusicSource= new ObservableCollection<Model.Music>();

And do everything on it and after that just say:

musicSource = _anotherMusicSource;

This will then trigger the notification and everything should work

Upvotes: 1

Charleh
Charleh

Reputation: 14002

You have an underscore in your property name

private ObservableCollection<Model.Musicmodel> musicSource= new ObservableCollection<Model.Musicmodel>();

public ObservableCollection<Model.Musicmodel> _musicSource
{
    get
    {
        return this.musicSource;
    }
    set
    {
        this.musicSource = value;
        RaisePropertyChanged("musicSource");
    }
 }

You have this mixed up - the underscore should (traditionally) be on the private member, not the public - your binding is targeting musicSource which is private

The standard convention which is advocated for .NET is:

// Private member variables
private int _someInteger;

// Public ones
public int SomeInteger { get { ... } set { ... } }

Upvotes: 1

Related Questions