我创建了一个类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
,但它没有帮助。我错过了什么?谢谢。
答案 0 :(得分:0)
您的代码中有两个问题需要解决。
首先,您应该知道ObservableCollection
通知其观察者有关其自身元素的更改,它不知道或不关心其元素属性的更改。换句话说,它不会监视其集合中的项目的属性更改通知。因此,更改Track
集合中的PlayList
对象属性值并不是任何意思。以下是关于该主题的article。
其次,您的MainWindowController根本不会广播NowPlayingTrackIndex
属性值更改。您应该致电NotifyPropertyChanged("NowPlayingTrackIndex")
以通知有趣的各方有关当前比赛赛道的变化。这可能会解决您的问题,但更优雅的方式,我的建议,将实现一个包含TrackObservableCollection
属性的自定义ObservableCollection类(类似NowPlaying
),而不是在MainWindowController类中实现它看起来像一个不必要的中介。