当项目被添加时,Observablecollection不更新列表

时间:2016-03-13 20:24:49

标签: c# wpf listview mvvm

我正在使用MVVM模式,并希望使用可观察的集合更新ListView。我经历了几个SO问题,但看不出我做错了什么。任何帮助深表感谢。感谢。

View.xaml

命名空间: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>();
    }
}

我确认项目肯定会添加到observable中。 再次感谢您的帮助。

4 个答案:

答案 0 :(得分:5)

将您的代码更改为:

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

只是解释原因:ViewModel的每个属性都应该通知它的更改。

答案 1 :(得分:1)

你应该把它写成itemsource

ItemsSource="{Binding ViewModel.TrackListObservable}"

并且还将窗口的数据上下文设置为自己。

<Window DataContext="{Binding RelativeSource={RelativeSource Self}}" ...

在MainWindow中使用此属性。

public AllTracksViewModel ViewModel { get; } = new AllTracksViewModel();

请注意,您必须向此属性添加项目。 ViewModel.TrackListObservable

您还应该删除

<UserControl.DataContext>
    <local:AllTracksViewModel/>
</UserControl.DataContext>

因为数据上下文是它自己的主窗口,这就是为什么itemsource被设置为ViewModel.TrackListObservable

答案 2 :(得分:1)

您的代码看起来正确。但是,我看不到填充TrackListObservable的方法。我建议你在构造函数中调用一个填充方法FillData。让我举个例子:

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

请参阅binding ListView using MVVM pattern.

的工作示例

答案 3 :(得分:0)

此处您的Property TrackListObservable 必须是INotify属性或依赖属性。因此,只有您可以获得所需的结果。

请参阅以下链接,了解INotify属性: https://msdn.microsoft.com/library/ms743695(v=vs.100).aspx