0

I have created a class Track which represents a song in the playlist:

public class Track
{
    public Uri Path
    {
        get { return path; }
        set { path = value; }
    }
    public TrackState State
    {
        get { return state; }
        set { state = value; }
    }

    private Uri path;
    private TrackState state;
}

Next I have created MainWindowController class which interacts between the UI window and the Track class:

public class MainWindowController : INotifyPropertyChanged
{
    public ObservableCollection<Track> Playlist
    {
        get { return playlist; }
        set
        {
            if (value != this.playlist)
            {
                playlist = value;
                NotifyPropertyChanged("Playlist");
            }
        }
    }
    public int NowPlayingTrackIndex
    {
        set
        {
            if (value >= 0)
            {
                playlist[nowPlayingTrackIndex].State = TrackState.Played;
                playlist[value].State = TrackState.NowPlaying;
                this.nowPlayingTrackIndex = value;
            }
        }
    }

    private ObservableCollection<Track> playlist;
    private int nowPlayingTrackIndex;
}

Basically, this class stores playlist collection and an index of the currently played track. Lastly, I have created the UI window in WPF:

<Window ...>
... 
<ListBox 
    Name="PlaylistListBox" 
    ItemsSource="{Binding Source={StaticResource ResourceKey=PlaylistViewSource}}" 
    ItemTemplateSelector="{Binding Source={StaticResource ResourceKey=TrackTemplateSelector}}" 
    MouseDoubleClick="PlaylistListBox_MouseDoubleClick" />
... 
</Window>

and the corresponding code behind:

...
private void PlaylistListBox_MouseDoubleClick(object sender, MouseButtonEventArgs e)
{
    int index = this.PlaylistListBox.SelectedIndex;
    this.windowController.NowPlayingTrackIndex = index;
} 
...

Items source points to the static resource where the CollectionViewSource is defined. The ItemTemplateSelector defines which DataTemplate to use for list box items depending on the track state (NowPlaying or Played).

When the user double-clicks the playlist item, the NowPlayingTrackIndex in the MainWindowController gets updated and it updates the track state. The problem is, the DataTemplates for list box items do not get updated on the window, i.e. the the double-clicked list box item does not change the data template. Why?

I tried setting the PropertyChanged for track state but it didn't help. What am I missing? Thank you.

Boris
  • 9,986
  • 34
  • 110
  • 147

1 Answers1

0

There are two issues to be addressed in your code.

First, you should know that ObservableCollection notify its observers about changes to its own elements, it doesn't know or care about changes to the properties of its elements. In other words, it doesn't watch for property change notification on the items within its collection. So changing the Track object property value in the PlayList collection doesn't watch by any mean. Here is an article about the subject.

Second, your MainWindowController doesn't broadcast for NowPlayingTrackIndex property value change at all. You should call NotifyPropertyChanged("NowPlayingTrackIndex") to notify interesting parties about the change of the current playing track. This may solve your problem but more elegant way, and my suggestion, would be implementing a custom ObservableCollection class (something like TrackObservableCollection) that contains NowPlaying property rather than implementing it in the MainWindowController class which looks like an unnecessary intermediation.

orka
  • 1,328
  • 8
  • 13
  • thank you for your answer. I do understand why my code doesn't work. However, I am having hard time implementing my own `ObservableCollection` class extension. Can you provide an example? Now an exact class of course (thought that would be fantastic of course), but just to understand how to implementation `Track` and `NowPlaying` properties. You may post a new answer or edit this one. Thank you for your answer, once again. Cheers. – Boris Mar 02 '11 at 23:37
  • Found it: http://stackoverflow.com/questions/1427471/c-observablecollection-not-noticing-when-item-in-it-changes-even-with-inotifyp – Boris Mar 03 '11 at 16:16