在MVVM中数据绑定ObservableCollection

我有一个带有Datatemplate的ListView,它包含一个电影列表。 它被数据绑定到ObservableColection但是每当我编辑Movie.Name时它都不会更新ListView,即使在我的PropertyChangedEventHandler中调用了“Name”并使用“Name”调用它。

我在我的初始化程序中为我的collections添加了2个“电影”,这些都显示正确(Klovn the Movie,Taken)

因此,当我单击编辑时,它应该更改所选电影的文本并将其名称更改为“测试”并且更改,但更改未显示在ListView中,但如果我使用foreach输出Collection,则Name为Test。

View.xaml

                           

View.cs

 using System; using System.Windows; using MovieDB3.Models; using MovieDB3.ViewModels; namespace MovieDB3 { ///  /// Interaction logic for MainWindow.xaml ///  public partial class MainWindow : Window { private MainViewModel MVM; public MainWindow() { InitializeComponent(); MVM = new MainViewModel(); DataContext = MVM; } private void MenuEditClick(object sender, RoutedEventArgs e) { MVM.setMovieName((Movie)ListViewMovies.SelectedItem, "test"); } } } 

ViewModel

 using System; using System.ComponentModel; using MovieDB3.Models; using System.Collections.ObjectModel; namespace MovieDB3.ViewModels { class MainViewModel : INotifyPropertyChanged { public ObservableCollection Collection {get; set;} public MainViewModel() { Collection = new ObservableCollection(); //Test kode Movie movie = new Movie(); movie.Name = "Klovn The Movie"; Collection.Add(movie); movie = new Movie(); movie.Name = "Taken"; Collection.Add(movie); } public void setMovieName(Movie movie, string newName) { //movie.Name = newName; Console.WriteLine("CurrentName: " + movie.Name); int i = Collection.IndexOf(movie); Collection[i].Name = newName; Console.WriteLine("NewName: " + movie.Name); NotifyPropertyChanged("Name"); } public void setMovieName(string currentName, string newName) { foreach (Movie movie in Collection) { if (movie.Name.Equals(currentName)) { movie.Name = newName; NotifyPropertyChanged("Name"); return; } } } //public string MovieName //{ // set // { // NotifyPropertyChanged("MovieName"); // } //} public event PropertyChangedEventHandler PropertyChanged; private void NotifyPropertyChanged(String info) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(info)); } } } } 

Movie.cs

 using System; namespace MovieDB3.Models { class Movie { public string Name { get; set; } public int Id { get; set; } public double Rating { get; set; } public DateTime Release { get; set; } public TimeSpan Runtime { get; set; } public String Trailer { get; set; } } } 

需要在Movie类中实现INotifyPropertyChanged ,同时避免手动引发事件。 (现在您告诉View ViewModel的属性“Name”已更改,但不存在)


你的class级可能是什么样的:

 public class Movie : INotifyPropertyChanged { private string _name = String.Empty; public string Name { get { return _name; } set { if (_name != value) { _name = value; NotifyPropertyChanged("Name"); } } } //...All the other properties (the same way)... public event PropertyChangedEventHandler PropertyChanged; public void NotifyPropertyChanged(string propertyName) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } } } 

您的更改方法减少到:

  public void setMovieName(Movie movie, string newName) { Console.WriteLine("CurrentName: " + movie.Name); movie.Name = newName; //The notification is now raised automatically in the setter of the property in the movie class Console.WriteLine("NewName: " + movie.Name); } 

我认为电影本身需要实现INotifyPropertyChanged。 您正在通过错误的对象(viewmodel)进行通知。

您还需要在Movie类上实现INotifyPropertyChanged。

您在setMovieName方法中发送的通知实际上并不意味着什么 – 它只是一个“属性”名称。 它也可以是“Foo”,你的事件处理程序会说“Foo”。

相反,您需要更新Movie对象本身。

可能最好的实现将是您创建一个通知INotifyPropertyChanged的抽象类,然后从中派生您的ViewModel和您的Movie类,因为两者都应该实现它。

您将从ViewModel绑定属性,并且您还将在ViewModel中绑定可观察对象(即Movie)。

目前,您正在让MainViewModelName更改引发NotifyPropertyChanged事件。 相反,您的Movie实例应该提升这些事件,因为您的Movie对象是具有该属性绑定的对象。