c# – 在MVVM中数据绑定ObservableCollection
发布时间:2020-12-15 23:57:20 所属栏目:百科 来源:网络整理
导读:我有一个带有Datatemplate的ListView,它包含一个电影列表.它被数据绑定到ObservableColection,但每当我编辑Movie.Name时,即使在我的PropertyChangedEventHandler中使用“Name”调用“Name”,它也不会更新ListView. 我在我的初始化程序中为我的收藏添加了2个
我有一个带有Datatemplate的ListView,它包含一个电影列表.它被数据绑定到ObservableColection,但每当我编辑Movie.Name时,即使在我的PropertyChangedEventHandler中使用“Name”调用“Name”,它也不会更新ListView.
我在我的初始化程序中为我的收藏添加了2个“电影”,这些都显示正确(Klovn the Movie,Taken) 因此,当我单击编辑时,它应该更改所选电影的文本并将其名称更改为“测试”并且已更改,但更改未显示在ListView中,但如果我使用foreach输出Collection,则Name is Test. View.xaml <Window x:Class="MovieDB3.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="350" Width="525"> <DockPanel> <Menu DockPanel.Dock="Top"> <MenuItem Header="File"> <MenuItem Header="Edit" Click="MenuEditClick"/> </MenuItem> </Menu> <Grid DockPanel.Dock="Top"> <Grid.ColumnDefinitions> <ColumnDefinition/> <ColumnDefinition/> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition/> </Grid.RowDefinitions> <ListView VerticalAlignment="Stretch" Name="ListViewMovies" ItemsSource="{Binding Path=Collection}" IsSynchronizedWithCurrentItem="True" > <ListView.ItemTemplate> <DataTemplate> <WrapPanel> <TextBlock Text="{Binding Path=Name}"/> </WrapPanel> </DataTemplate> </ListView.ItemTemplate> </ListView> </Grid> </DockPanel> </Window> View.cs using System; using System.Windows; using MovieDB3.Models; using MovieDB3.ViewModels; namespace MovieDB3 { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> 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<Movie> Collection {get; set;} public MainViewModel() { Collection = new ObservableCollection<Movie>(); //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; } } } 解决方法
INotifyPropertyChanged需要在Movie类中实现,也避免手动引发事件.
(现在你告诉View,ViewModel的属性“Name”发生了变化,但是不存在) 你的班级可能是什么样的: 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); } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |