WPF 中双向绑定通知机制之ObservableCollection使用
2021-05-03 03:26
标签:generic document 有一个 点击 edit tps inpu str article msdn中 ObservableCollectionT> 类 表示一个动态数据集合,在添加项、移除项或刷新整个列表时,此集合将提供通知。
在许多情况下,所使用的数据是对象的集合。 例如,数据绑定中的一个常见方案是使用 ItemsControl(如 ListBox、ListView 或 TreeView)来显示记录的集合。
可以枚举实现 IEnumerable 接口的任何集合。 但是,若要设置动态绑定,以便集合中的插入或删除操作可以自动更新 UI,则该集合必须实现 INotifyCollectionChanged 接口。 此接口公开 CollectionChanged 事件,只要基础集合发生更改,都应该引发该事件。
WPF 提供 ObservableCollection
还有许多情况,我们所使用的数据只是单纯的字段或者属性,此时我们需要为这些字段或属性实现INotifyPropertyChanged接口,实现了该接口,只要字段或属性的发生了改变,就会提供通知机制。
ObservableCollection>实现
前台xmal


后台cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Collections.ObjectModel;
using System.ComponentModel;
namespace WpfApplication1
{
public partial class WindowObservable : Window
{
ObservableCollection infos = new ObservableCollection() {
new Students(){ Id=1, Age=11, Name="Tom"},
new Students(){ Id=2, Age=12, Name="Darren"},
new Students(){ Id=3, Age=13, Name="Jacky"},
new Students(){ Id=4, Age=14, Name="Andy"}
};
public WindowObservable()
{
InitializeComponent();
this.lbStudent.ItemsSource = infos;
this.txtStudentId.SetBinding(TextBox.TextProperty, new Binding("SelectedItem.Id") { Source = lbStudent });
}
private void button1_Click(object sender, RoutedEventArgs e)
{
infos[1] = new Students() { Id = 4, Age = 14, Name = "这是一个集合改变" };
infos[2].Name = "这是一个属性改变";
}
public class Students
{
public int Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
}
}
}

在这个例子中我们将Students数据对象用ObservableCollection


INotifyPropertyChanged实现
INotifyPropertyChanged会向客户端发出某一属性值已更改的通知。当元素属性值改变时,会通知后台model
前台代码不变,我们让后台Students Model实现INotifyPropertyChanged接口。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Collections.ObjectModel;
using System.ComponentModel;
namespace WpfApplication1
{
public partial class WindowObservable : Window
{
ObservableCollection infos = new ObservableCollection() {
new Students(){ Id=1, Age=11, Name="Tom"},
new Students(){ Id=2, Age=12, Name="Darren"},
new Students(){ Id=3, Age=13, Name="Jacky"},
new Students(){ Id=4, Age=14, Name="Andy"}
};
public WindowObservable()
{
InitializeComponent();
this.lbStudent.ItemsSource = infos;
this.txtStudentId.SetBinding(TextBox.TextProperty, new Binding("SelectedItem.Id") { Source = lbStudent });
}
private void button1_Click(object sender, RoutedEventArgs e)
{
infos[1] = new Students() { Id = 4, Age = 14, Name = "这是一个集合改变" };
infos[2].Name = "这是一个属性改变";
}
public class Students : INotifyPropertyChanged
{
string _name;
public int Id { get; set; }
public string Name
{
get { return _name; }
set { _name = value; OnPropertyChanged("Name"); }
}
public int Age { get; set; }
protected internal virtual void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
public event PropertyChangedEventHandler PropertyChanged;
}
}
}

此时我们再 运行代码会发现

使用DataContext为页面对象设置上下文
不管是集合还是对象都发生了改变。至此。我们的整个后台通知就能完美监视任何对象变动。
但是现在还有一个问题。我们如果在点击事件里面给infos赋值一个新的集合数据。如下

private void button1_Click(object sender, RoutedEventArgs e)
{
infos[1] = new Students() { Id = 4, Age = 14, Name = "这是一个集合改变" };
infos[2].Name = "这是一个属性改变";
infos = new ObservableCollection() { new Students(){ Id=1, Age=11, Name="这是改变后的集合"}, new Students(){ Id=2, Age=12, Name="这是改变后的集合"}, new Students(){ Id=3, Age=13, Name="这是改变后的集合"}, new Students(){ Id=4, Age=14, Name="这是改变后的集合"} };
}

会发现数据并没有变更。这是为什么?我们明明实现了ObservableCollection

public class ViewModel : INotifyPropertyChanged
{
private ObservableCollection studentList;
public ObservableCollection StudentList
{
get
{
return this.studentList;
}
set
{
if (this.studentList != value)
{
this.studentList = value;
OnPropertyChanged("StudentList");
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = this.PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}

windowsObservable类修改为如下

public partial class WindowObservable : Window
{
ViewModel viewModel = new ViewModel();
public WindowObservable()
{
InitializeComponent();
viewModel.StudentList = new ObservableCollection() {
new Students(){ Id=1, Age=11, Name="Tom"},
new Students(){ Id=2, Age=12, Name="Darren"},
new Students(){ Id=3, Age=13, Name="Jacky"},
new Students(){ Id=4, Age=14, Name="Andy"}
};
this.lbStudent.DataContext = viewModel;
}
private void button1_Click(object sender, RoutedEventArgs e)
{
viewModel.StudentList[1] = new Students() { Id = 4, Age = 14, Name = "这是一个集合改变" };
viewModel.StudentList = new ObservableCollection() {
new Students(){ Id=19, Age=111, Name="这是变化后的几何"},
new Students(){ Id=29, Age=121, Name="这是变化后的几何"},
new Students(){ Id=39, Age=131, Name="这是变化后的几何"},
new Students(){ Id=49, Age=141, Name="这是变化后的几何"}
};
viewModel.StudentList[2].Name = "这是一个属性改变";
}
}

我们给xaml listbox设置如下绑定
ItemsSource="{Binding StudentList, Mode=TwoWay}"
运行程序我们发现集合的改变也会被通知到前台。

代码参考:http://blog.csdn.net/fwj380891124/article/details/8194190
本文地址:http://www.cnblogs.com/santian/p/4366832.html
博客地址:http://www.cnblogs.com/santian/
WPF 中双向绑定通知机制之ObservableCollection使用
标签:generic document 有一个 点击 edit tps inpu str article
原文地址:http://www.cnblogs.com/sjqq/p/7755322.html
文章标题:WPF 中双向绑定通知机制之ObservableCollection使用
文章链接:http://soscw.com/essay/81614.html