数据绑定ListBox不会更新

时间:2011-03-01 05:04:26

标签: wpf binding

我创建了一个类Track,代表播放列表中的一首歌:

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;
}

接下来我创建了MainWindowController类,它在UI窗口和Track类之间进行交互:

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;
}

基本上,此类存储播放列表集合和当前播放曲目的索引。最后,我在WPF中创建了UI窗口:

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

以及相应的代码:

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

项目源指向定义CollectionViewSource的静态资源。 ItemTemplateSelector根据跟踪状态(NowPlaying或Played)定义用于列表框项目的DataTemplate

当用户双击播放列表项时,NowPlayingTrackIndex中的MainWindowController会更新,并会更新跟踪状态。问题是,列表框项的DataTemplates没有在窗口上更新,即双击列表框项不会更改数据模板。为什么?

我尝试为跟踪状态设置PropertyChanged,但它没有帮助。我错过了什么?谢谢。

1 个答案:

答案 0 :(得分:0)

您的代码中有两个问题需要解决。

首先,您应该知道ObservableCollection通知其观察者有关其自身元素的更改,它不知道或不关心其元素属性的更改。换句话说,它不会监视其集合中的项目的属性更改通知。因此,更改Track集合中的PlayList对象属性值并不是任何意思。以下是关于该主题的article

其次,您的MainWindowController根本不会广播NowPlayingTrackIndex属性值更改。您应该致电NotifyPropertyChanged("NowPlayingTrackIndex")以通知有趣的各方有关当前比赛赛道的变化。这可能会解决您的问题,但更优雅的方式,我的建议,将实现一个包含TrackObservableCollection属性的自定义ObservableCollection类(类似NowPlaying),而不是在MainWindowController类中实现它看起来像一个不必要的中介。