WPF笔记12——List<T> 与 ObservableCollection<T>
代码1,使用ObservableCollection<T>:
/*
优点:
(1)使用ObservableCollection<Student>来存储学生数据。在WPF中,ObservableCollection是一个非常适合数据绑定的集合类型。
当集合中的元素发生变化(如添加、删除、修改元素)时,它会自动通知UI更新,这符合MVVM模式下视图与视图模型之间数据绑定的需求,使得UI能够及时响应数据的变化.
(2)在WPF开发中,ObservableCollection是处理动态数据集合的标准方式。使用它有助于编写更易于维护和扩展的代码,特别是在涉及到数据驱动的UI场景下,如显示学生列表并且列表可能会动态变化(例如添加新学生或删除现有学生)。
缺点:
(1)ObservableCollection为了实现元素变更通知功能,会有一定的性能开销。如果应用场景中集合数据非常庞大,并且变更操作非常频繁,这种开销可能会对性能产生一定的影响。不过在大多数常规的WPF应用场景中,这种影响通常是可以接受的。
*/
using System.Collections.ObjectModel;
using System.ComponentModel;
public class StudentViewModel : INotifyPropertyChanged
{
private ObservableCollection<Student> _students;
public StudentViewModel()
{
_students = new ObservableCollection<Student>
{
new Student { Name = "John Doe", Age = 21 },
new Student { Name = "Jane Smith", Age = 22 }
};
}
public ObservableCollection<Student> Students
{
get => _students;
set
{
_students = value;
OnPropertyChanged(nameof(Students));
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
代码2,使用List<T>:
/*
优点:
(1)使用List<Student>是一种简单直接的方式来存储学生数据。List是C#中的基本集合类型,相比于ObservableCollection,它的性能在某些情况下可能更好,特别是在只需要进行简单的读取操作而不需要关注集合变更通知的场景下。
(2)如果应用场景中不需要集合变更自动通知UI(例如数据只是一次性加载并且不会再发生改变),List是一个更简洁的选择。代码的逻辑相对简单,没有ObservableCollection为了实现变更通知而带来的额外复杂性。
缺点:
(1)不支持自动数据绑定更新。
在WPF的MVVM模式下,如果视图绑定到这个List类型的Students属性,当List中的元素发生变化(如添加、删除元素)时,UI不会自动得到通知进行更新。
这就需要手动编写额外的代码来实现类似的功能,这违背了MVVM模式中视图和视图模型松耦合的原则,增加了代码的维护难度。
*/
using System.Collections.ObjectModel;
using System.ComponentModel;
public class StudentViewModel : INotifyPropertyChanged
{
private List<Student> _students;
public StudentViewModel()
{
_students = new List<Student>
{
new Student { Name = "John Doe", Age = 21 },
new Student { Name = "Jane Smith", Age = 22 }
};
}
public List<Student> Students
{
get => _students;
set
{
_students = value;
OnPropertyChanged(nameof(Students));
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
-
ObservableCollection<T>
的特性- 自动通知机制:
ObservableCollection<T>
是一个动态数据集合,它实现了INotifyCollectionChanged
接口。
这意味着当集合中的项被添加、删除或整个集合被重置时,它会自动触发CollectionChanged
事件。
例如,在一个WPF的用户界面中,如果一个ListView
的数据绑定到一个ObservableCollection<string>
,当向这个集合中添加一个新的字符串时,ListView
会自动更新以显示新的内容,而不需要手动触发任何更新操作。 - 与数据绑定的无缝集成:在WPF中,数据绑定是MVVM模式的核心部分。
ObservableCollection<T>
与数据绑定系统紧密配合,使得视图能够自动响应集合的变化。
当使用List<T>
结合OnPropertyChanged
时,它只能通知属性(集合本身)的变化,比如当整个集合被替换时。
但是如果只是集合中的一个元素被添加、删除或修改,List<T>
不会自动通知视图更新。
而ObservableCollection<T>
会在这些更细粒度的变化发生时,如Add
、Remove
、Insert
等操作,自动发出通知,使视图能够及时更新。
- 自动通知机制:
-
List<T>
结合OnPropertyChanged
的局限性- 手动更新负担重:如果使用
List<T>
并通过OnPropertyChanged
来通知变化,当对列表中的元素进行操作(如添加、删除或修改元素)时,需要在代码中手动触发OnPropertyChanged
事件。
例如,假设在视图模型中有一个List<string>
属性MyList
,在向MyList
中添加一个新元素后,需要手动调用OnPropertyChanged("MyList")
来通知视图更新。
这种手动触发的方式容易出错,而且如果有多个地方对列表进行操作,很容易遗漏更新通知。 - 只能通知集合整体变化:
OnPropertyChanged
主要是用于通知属性值的改变。对于List<T>
,它只能有效地通知视图当整个列表被重新赋值(例如MyList = new List<string>()
)这种情况。
如果只是列表中的元素发生了变化,如MyList[0] = "New Value"
,视图不会自动更新,除非额外编写复杂的代码来处理这种元素级别的变化通知。
- 手动更新负担重:如果使用
-
总结
- 推荐使用
ObservableCollection<T>
是因为它提供了更方便、更自动的方式来处理集合的变化通知,减少了手动更新的工作量,并且能够更精细地与WPF的数据绑定系统协同工作,确保视图能够及时、准确地反映数据模型中的集合变化。这符合MVVM模式中视图和视图模型之间松耦合、自动更新的原则,提高了代码的可维护性和可读性。
- 推荐使用