WinUI3入门2:DataGrid动态更新 添加删除和修改字段

初级代码游戏的专栏介绍与文章目录-CSDN博客

我的github:codetoys,所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。

这些代码大部分以Linux为目标但部分代码是纯C++的,可以在任何平台上使用。

源码指引:github源码指引_初级代码游戏的博客-CSDN博客

C#是我多年以来的业余爱好,新搞的东西能用C#的就用C#了。


承接上一篇:WinUI3入门1:使用DataGrid控件显示表格-CSDN博客

上一篇我们已经显示了表格,但是只显示一般是不够的,我们还要考虑动态修改。本篇我们解决对数据源的修改如何反映到DataGrid控件的问题。

说起来"修改"是一个问题,但是分解开是两个完全不同的问题:

  • 添加和删除如何反应到界面
  • 修改字段如何反映到界面

因为容器的"修改"是添加和删除,而字段的修改属于容器里的每个对象,技术上是完全不同的。

一、添加和删除如何反映到界面

DataGrid通过ItemSource绑定到数据源,数据源要求是个IEnumerable,通常用List<>,然而,List<>并没有变化通知的功能,因此我们之前用List<>无论如何都不能实现数据源添加修改反映到界面。

为了让DataGrid能够得到数据源变化通知,需要使用另一个模板:ObservableCollection<>。简单替换之后数据源的增加和删除就能立即反映到界面上了。

通过点击按钮给数据源增加数据:

cs 复制代码
			Data tmp = new Data("aa", "", "", "");
			datas.Add(tmp);
			datas[0].Dir = datas.Count.ToString();注意此句尚不会更新到界面

            datas[0].File = datas.Count.ToString();注意此句尚不会更新到界面

效果如下:

注意,修改字段是不会反映上去的,即使隐藏控件然后再显示也不行。但是如果数据很多发生了滚动,一条数据重新出现时会显示为更新后的数据。(注:上图是已经添加了字段变化通知的效果,第一行第一列第二列已经被修改)

二、修改界面如何反应到字段

2.1 INotifyPropertyChanged

能够通知字段变化的数据类型必须支持INotifyPropertyChanged接口。该接口包含一个事件:

cs 复制代码
event PropertyChangedEventHandler PropertyChanged;

此事件在属性更改时发生。实现此接口的数据类型需要在每个属性更改是触发此事件。

2.2 实现INotifyPropertyChanged

实现过程相当繁琐,C#在引入无数令人困惑的语法甜点之后,为什么不给加个关键字指示一下呢?

以下是新的Data类的代码:

cs 复制代码
		public class Data : INotifyPropertyChanged
		{
			String _dir;
			String _file;
			public String Dir { get { return _dir; } set { _dir = value; OnPropertyChanged(); } }
			public String File { get { return _file; } set { _file = value; OnPropertyChanged(); } }
			public String Ext { get; set; } = "";
			public String Type { get; set; } = "";
			public String Encode { get; set; } = "";
			public String BOM { get; set; } = "";
			public int CR { get; set; } = 0;
			public int CRLF { get; set; } = 0;
			public int LF { get; set; } = 0;
			public String State { get; set; } = "";

			public event PropertyChangedEventHandler PropertyChanged = delegate { };
			public void OnPropertyChanged([CallerMemberName] string propertyName="")
			{
				// Raise the PropertyChanged event, passing the name of the property whose value has changed.
				PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
			}
			public Data(String str, String n,
				String str2, String b)
			{
				this.Dir = str;
				this.Ext = n;
				this.File = str2;
				this.State = b;
			}

			public static ObservableCollection<Data> Datas()
			{
				return new ObservableCollection<Data>(new Data[4] {
			new Data("a", "1",
				"aaa",
				"false"),
			new Data("b","2",
				"bbb",
				"false"),
			new Data("c", "3",
				"ccc",
				"true"),
			new Data("d", "4",
				"ddd",
				"true")
		});
			}
		}

定义INotifyPropertyChanged要求的事件:

cs 复制代码
			public event PropertyChangedEventHandler PropertyChanged = delegate { };

实现辅助的触发时间函数,以简化每个属性的代码:

cs 复制代码
			public void OnPropertyChanged([CallerMemberName] string propertyName="")
			{
				// Raise the PropertyChanged event, passing the name of the property whose value has changed.
				PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
			}

一个属性的实现:

cs 复制代码
			String _dir;
			public String Dir { get { return _dir; } set { _dir = value; OnPropertyChanged(); } }

我们还记得原来的写法很简单:

cs 复制代码
public String Dir { get; set; } = "";

为什么复杂了这么多?

  • 因为要调用函数触发事件,set必须写出来
  • 因为set必须写出来,就必须先给自己赋值
  • 在set里给自己赋值会触发set,无限递归
  • 所以不能使用简化属性语法,必须额外定义一个实际变量
  • 因此get也必须写出来

对每一个需要实时更新界面的属性都要这样写。

三、xaml设置和代码设置

xaml可以设置Mode为单项或双向,代码设置ItemSource时没有设置的地方,目前看至少是OneWay方式,是否支持双向,我们以后再研究。


(这里是文档结束)

相关推荐
绿荫阿广7 个月前
WinUI(WASDK)使用BotSharp框架开发多智能体桌面机器人管理助手(生图开关灯不在话下)
c#·.net·winui
Vicky&James7 个月前
英雄联盟客户端项目:从跨平台Uno Platform到Win UI3的转换只需要30分钟
github·wpf·跨平台·英雄联盟·winui·unoplatform
绿荫阿广10 个月前
使用Aspire优雅的进行全栈开发——WinUI使用Semantic Kernel调用智普清言LLM总结Asp.Net Core通过Playwright解析的网页内容
asp.net core·winui·semantic kernel
贝格前端工场1 年前
WPF是不是垂垂老矣啦?平替它的框架还有哪些
qt·前端框架·wpf·ump·winui·winforms
wocwin1 年前
原生微信小程序如何动态修改svg图片颜色及尺寸、宽高(封装svgIcon组件)解决ios不显示问题
微信小程序·小程序·svg图片·修改svg图片颜色·动态修改
绿荫阿广2 年前
.Net 8与硬件设备能碰撞出怎么样的火花(使用ImageSharp和Protobuf协议通过HidApi与设备通讯)
c#·.net·winui