C# ListView 控件和 INotifyPropertyChanged 接口

ListView 控件和 DataGridView 控件

ListView 是跟 Winform 中 DataGridView 用法以及显示效果差不多的一个 WPF 控件,可以通过列表的方式方便的显示数据;

<!-- ListView 控件 Xaml 代码 -->
<ListView Name="listView" Margin="10,10,9.6,10">
	<ListView.View>
		<GridView>
			<GridViewColumn Header="任务"/>
			<GridViewColumn Header="任务描述"/>
			<GridViewColumn Header="循环周期(秒)"/>
			<GridViewColumn Header="任务状态/>
		</GridView>
	</ListView.View>
</ListView>

DataGridView 控件的使用中,通常我们都会创建一个类用来储存数据,读取数据之后再创建一个这个类的集合,然后将集合赋给 dataGridView1.DataSource 属性;也可不用集合,直接在循环中把数据一条一条的加载 dateGridView1.Rows.Add()

// 先创建一个用来储存数据的类
class UserInfo
{
    public string Name { get; set; }
    public int Age { get; set; }
}
// WinForm:DataGridView 控件
// 方法一:创建一个对象集合,赋值给 DataSource 属性
List<UserInfo> infos = new List<UserInfo>();
for(int i = 0; i > 10; i++)
{
    infos.Add(new UserInfo
    {
		Name = $"Light_{i}",
        Age = i
	});
}
dataGridView1.DataSource = infos;

// 方法二:一条一条的添加数据
for(int i = 0; i > 10; i++)
{
    dateGridView1.Rows.Add(new UserInfo
    {
		Name = $"Light_{i}",
        Age = i
	});
}

在 ListView 控件中 DataSource 属性在这里是 listView.ItemsSource;单条数据加载的方法是 listView.Items.Add();,整体用法还是大同小异;

// WPF:ListView 控件
// 方法一:创建一个对象集合,赋值给 ItemsSource 属性
List<UserInfo> infos = new List<UserInfo>();
for(int i = 0; i > 10; i++)
{
    infos.Add(new UserInfo
    {
		Name = $"Light_{i}",
        Age = i
	});
}
listView.ItemsSource = infos;

// 方法二:一条一条的添加数据
for(int i = 0; i > 10; i++)
{
    listView.Items.Add(new UserInfo
    {
		Name = $"Light_{i}",
        Age = i
	});
}

INotifyPropertyChanged 接口

命名空间:System.ComponentModel

INotifyPropertyChanged 是一个非常强大的接口,用于向对象绑定的客户端控件发出对象属性已更改的通知;

用人话说就是:正常我们向上面一样,把对象绑定到控件用来显示数据,有一个缺点:每次更改对象的属性之后,我们需要手动的重新再去绑定数据,否则数据是不会刷新显示修改后的值的;

但是如果对象实现了 INotifyPropertyChanged 接口的话,我们根本不用担心这些问题,直接修改已绑定对象的属性,客户端就会自动刷新显示数据;

比如说,上面我们创建的 UserInfo 类就可以修改成这样:

class UserInfo : System.ComponentModel.INotifyPropertyChanged
{
    private string name;
    private int age;
    
    // 属性发生更改时触发的事件,由每个属性的 Set 访问器调用
    public event PropertyChangedEventHandler PropertyChanged;
    
    public string Name
    {
    	get => name;
    	set
        {
        	name = value;
        	PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Name"));
        }
    }
    public string Age
    {
    	get => age;
    	set
        {
        	age = value;
        	PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Age"));
        }
    }
}

注意,我们为 UserInfo 类实现了 INotifyPropertyChanged 接口后,就不能用 List<T> 去创建集合了,需要用 ObservableCollection<T> 来创建 UserInfo 对象实例的集合;

因为List<T> 集合是强类型的 object 集合,绑定完成之后再进行修改添加操作是没办法通知已绑定的客户端控件的;

Observablecollection<T> 是动态数据集合,当 ObservableCollection<T> 添加一项时,会自动通知绑定的控件做相应修改;如果希望当 ObservableCollection<T> 集合中对象的属性发生改变时通知 UI,则 T 需要实现 INotifyPropertyChanged 接口;

// 用 Observablecollection<T> 创建集合
Observablecollection<UserInfo> infos = new Observablecollection<UserInfo>();
infos.Add(new UserInfo
{
    Name = "Light",
    Age = 18
});

// 为 DataGridView 控件绑定对象
dataGridView1.DataSource = infos;

// 为 ListView 控件绑定对象
listView.ItemsSource = infos;

之后每次修改数据,就可以直接获取绑定的对象然后修改对象属性就可以了,无需再做任何操作;

// DataGridView 控件
// 获取选中行,返回当前绑定对象
UserInfo info = (UserInfo)dataGridView1.SelectedRows[0].DataBoundItem;
info.Name = "Liang";
info.Age = 18;
// ListView 控件
// 获取选中行,返回当前绑定对象
UserInfo info = (UserInfo)listView.SelectedItem;
info.Name = "Liang";
info.Age = 18;
posted @ 2019-04-19 12:16  Lianginx  阅读(1013)  评论(0编辑  收藏  举报