问题
I'm using the MVVM pattern and want to update a ListView using an observable collection. I went through several SO questions, but cannot see what I'm doing wrong. Any help is much appreciated. Thanks.
View.xaml
Namespace: xmlns:local="clr-namespace:MusicPlayer.ViewModel"
DataContext
<UserControl.DataContext>
<local:AllTracksViewModel/>
</UserControl.DataContext>
ListView
<ListView x:Name="TrackListView"
ItemsSource="{Binding Path=TrackListObservable}">
...
<ListView.View>
<GridView>
<GridViewColumn Header="Title" Width="250" DisplayMemberBinding="{Binding Title}" />
<GridViewColumn Header="Album" Width="200" DisplayMemberBinding="{Binding Album}" />
<GridViewColumn Header="Artist" Width="150" DisplayMemberBinding="{Binding Artist}" />
<GridViewColumn Header="Duration" Width="100" DisplayMemberBinding="{Binding FormattedDuration}" />
</GridView>
</ListView.View>
</ListView>
ViewModel.cs
public class AllTracksViewModel
{
public ObservableCollection<Track> TrackListObservable { get; private set; }
public AllTracksViewModel()
{
TrackListObservable = new ObservableCollection<Track>();
}
}
I verified that items are definitely getting added to the observable. Again, thanks for the help.
回答1:
Change your code to this:
public class AllTracksViewModel : INotifyPropertyChanged
{
ObservableCollection<Track> trackListObservable;
public event PropertyChangedEventHandler PropertyChanged;
public ObservableCollection<Track> TrackListObservable {
get { return trackListObservable; }
set {
trackListObservable = value;
if(PropertyChanged!=null) {
PropertyChanged(this, new PropertyChangedEventArgs("TrackListObservable"));
}
}
}
public AllTracksViewModel()
{
TrackListObservable = new ObservableCollection<Track>();
}
}
Just to explain why: every property of your ViewModel should notify of its changes.
回答2:
You should write this as itemsource
ItemsSource="{Binding ViewModel.TrackListObservable}"
And also set data context of windows to it self.
<Window DataContext="{Binding RelativeSource={RelativeSource Self}}" ...
With this property in MainWindow.
public AllTracksViewModel ViewModel { get; } = new AllTracksViewModel();
Note that you have to add items to this property. ViewModel.TrackListObservable
You should also remove
<UserControl.DataContext>
<local:AllTracksViewModel/>
</UserControl.DataContext>
since the data context is the main window it self, thats why itemsource is set to ViewModel.TrackListObservable
回答3:
Your code looks correctly. However, I cannot see the method which populates your TrackListObservable
. I suggest to you to call a populating method FillData
inside of a constructor. Let me show an example:
public class AllTracksViewModel
{
private ObservableCollection<Track> _trackListObservable;
public ObservableCollection<Track> TrackListObservable
{
get { return _trackListObservable; }
set {
_trackListObservable = value;
}
}
public AllTracksViewModel()
{
FillData();
}
private void FillData()
{
_trackListObservable = new ObservableCollection<Track>();
for (int i = 0; i < 30; i++)
{
TrackListObservable.Add(new Track() { Title = "Ben & Joseph " + i.ToString(),
Artist = "Albahari" });
}
}
}
Please, see a work example of binding ListView using MVVM pattern.
回答4:
Here your Property TrackListObservable must be a INotify Property or Dependency Property.So that only you can achieve the result what you want.
Refer the below link regards INotify Property: https://msdn.microsoft.com/library/ms743695(v=vs.100).aspx
来源:https://stackoverflow.com/questions/35975364/observablecollection-not-updating-list-when-an-item-gets-added