WPF 中集合 ObservableCollection<T>的使用

news2024/11/17 19:36:31

C#集合类ObservableCollection<T>
类似于泛型列表类List<T>,表示一个动态数据收集,该集合在添加或删除项或刷新整个列表时提供通知。

所在命名空间:System.Collections.ObjectModel

继承关系:

public class ObservableCollection<T> : Collection<T>, INotifyCollectionChanged, INotifyPropertyChanged

参考微软官方网站

ObservableCollection

有两个重要的事件
public event NotifyCollectionChangedEventHandler CollectionChanged;
protected event PropertyChangedEventHandler PropertyChanged;

实现

INotifyCollectionChanged  INotifyPropertyChanged

注解
在许多情况下,你使用的数据是 对象的集合。 例如,数据绑定中的常见方案是使用 ItemsControl (如 、 ListView或 TreeView )ListBox来显示记录集合。

你可以枚举实现 IEnumerable 接口的任何集合。 但是,若要设置动态绑定,以便集合中的插入或删除操作可以自动更新 UI,则集合必须实现 INotifyCollectionChanged 接口。 此接口公开 CollectionChanged 事件,只要基础集合发生更改,就会引发该事件。

WPF 提供 ObservableCollection<T> 类,该类是实现 INotifyCollectionChanged 接口的数据收集的内置实现。

在实现自己的集合前,请考虑使用 ObservableCollection<T> 或现有集合类之一,例如 List<T>、Collection<T> 和 BindingList<T> 等。 如果你有一个高级方案并且想要实现自己的集合,请考虑使用 IList,它提供可由索引单独访问的对象的非泛型集合。 实现 IList 提供数据绑定引擎的最佳性能。

注意

若要完全支持将数据值从绑定源对象传输到绑定目标,集合中支持可绑定属性的每个对象都必须实现适当的属性更改通知机制,例如 INotifyPropertyChanged 接口。

测试使用ObservableCollection
新建WPF应用程序DataGridDemo,在默认的MainWindow.xaml设计器中添加DataGrid和Button

 MainWindow.xaml的设计器相关代码如下:

窗体绑定Loaded事件,按钮绑定Click事件

<Window x:Class="DataGridDemo.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:DataGridDemo"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800" Loaded="Window_Loaded">
    <Grid Margin="0,0,-49,0">
        <DataGrid Name="dgTest" ItemsSource="{Binding}" AutoGenerateColumns="False" HorizontalAlignment="Left" Height="387" Margin="6,6,0,0" VerticalAlignment="Top" Width="699">
            <DataGrid.Columns>
                <DataGridTextColumn Binding="{Binding EnglishName}" Width="120" Header="Mes名称"/>
                <DataGridTextColumn Binding="{Binding FieldName}" Width="120" Header="字段名称"/>
                <DataGridTextColumn Binding="{Binding MappingName}" Width="120" Header="映射名称"/>
                <DataGridTextColumn Binding="{Binding ChineseName}" Width="120" Header="中文名称"/>
                <DataGridTextColumn Binding="{Binding DataType}" Width="120" Header="数据类型"/>
                <DataGridTextColumn Binding="{Binding Value}" Width="120" Header="当前值"/>
            </DataGrid.Columns>
        </DataGrid>
        <Button x:Name="btnSaveEdit" Content="保存编辑后的数据" HorizontalAlignment="Left" Margin="712,16,0,0" VerticalAlignment="Top" Width="101" Height="58" Click="btnSaveEdit_Click"/>
 
    </Grid>
</Window>

新建测试绑定类ParametricData

ParametricData.cs如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace DataGridDemo
{
    /// <summary>
    /// 需要上传的某条生产数据,由name,value,dataType等组成
    /// </summary>
    public class ParametricData
    {
        /// <summary>
        /// 中文名称,该上传数据项的描述
        /// </summary>
        public string ChineseName { get; set; }
        /// <summary>
        /// 英文名称,上传数据的键名。例如:SCGL1【输出功率1】
        /// </summary>
        public string EnglishName { get; set; }
        /// <summary>
        /// 数据表的列名或字段名,与EnglishName组成对应关系。用于手动上传出站数据时,从数据表查找数据绑定到指定的键上
        /// </summary>
        public string FieldName { get; set; }
        /// <summary>
        /// PLC地址表配置的英文名称,与EnglishName组成映射关系,用于获取实际的生产数据值
        /// </summary>
        public string MappingName { get; set; }
        /// <summary>
        /// 数据类型
        /// </summary>
        public string DataType { get; set; }
        /// <summary>
        /// 当前值
        /// </summary>
        public string Value { get; set; }
    }
}

MainWindow.xaml.cs相关处理代码如下

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
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.Navigation;
using System.Windows.Shapes;
 
namespace DataGridDemo
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        //List<ParametricData> ParametricDataList = new List<ParametricData>();
        System.Collections.ObjectModel.ObservableCollection<ParametricData> ParametricDataList = new System.Collections.ObjectModel.ObservableCollection<ParametricData>();
        public MainWindow()
        {
            InitializeComponent();
        }
 
        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            for (int i = 0; i < 10; i++)
            {
                ParametricDataList.Add(new ParametricData()
                {
                    EnglishName = $"TestData{i + 1}",
                    ChineseName = $"测试数据{i + 1}",
                    FieldName = $"TestData{i + 1}",
                    MappingName = $"TestData{i + 1}",
                    DataType = "数字",
                    Value = new Random(Guid.NewGuid().GetHashCode()).Next(1, 1000).ToString("D3"),
                });
            }
            dgTest.DataContext = ParametricDataList;
        }
 
        private void btnSaveEdit_Click(object sender, RoutedEventArgs e)
        {
            int affectCount = 0;
            for (int i = 0; i < dgTest.Items.Count; i++)
            {
                ParametricData parametricData = dgTest.Items.GetItemAt(i) as ParametricData;
                if (parametricData == null || string.IsNullOrWhiteSpace(parametricData.EnglishName)) 
                {
                    continue;
                }
                WriteLogCsv(AppDomain.CurrentDomain.BaseDirectory + "test.csv", parametricData);
                affectCount++;
            }
            MessageBox.Show($"保存编辑后的数据成功,保存数据条数:【{affectCount}】");
        }
 
        /// <summary>
        /// 写CSV日志 按列显示
        /// </summary>
        /// <param name="fileName">写入的csv文件名,全路径</param>
        /// <param name="barcode">条码</param>
        /// <param name="responseResult">MES请求与返回信息对象</param>
        /// <returns></returns>
        public static bool WriteLogCsv(string fileName, ParametricData parametricData)
        {
            try
            {
                string directoryPath = System.IO.Path.GetDirectoryName(fileName);
                if (!Directory.Exists(directoryPath))
                {
                    Directory.CreateDirectory(directoryPath);
                }
                string columnContents = "Mes名称,字段名称,映射名称,中文名称,数据类型,当前值\r\n";
                if (!File.Exists(fileName))
                {
                    File.AppendAllText(fileName, columnContents, Encoding.Default);
                }
 
                StringBuilder sb = new StringBuilder();
                using (StreamWriter write = new StreamWriter(fileName, true, Encoding.Default))
                {
                    sb.Append($"{parametricData.EnglishName},");
                    sb.Append($"{parametricData.FieldName},");
                    sb.Append($"{parametricData.MappingName},");
                    sb.Append($"{parametricData.ChineseName},");
                    sb.Append($"{parametricData.DataType},");
                    sb.Append($"{ProcessPunctuationForCsv(parametricData.Value)}");
                    write.WriteLine(sb.ToString());
                }
                return true;
            }
            catch (Exception ex)
            {
                MessageBox.Show("CSV文件写入失败:" + ex.Message);
                return false;
            }
        }
 
        /// <summary>
        /// 处理csv文件中的双引号和逗号,使其在Excel中完美显示为一个单元格
        /// </summary>
        /// <param name="srcStr"></param>
        /// <returns></returns>
        private static string ProcessPunctuationForCsv(string srcStr)
        {
            if (srcStr == null)
            {
                return string.Empty;
            }
            bool quoteFlag = false;//是否添加过双引号
            //如果存在双引号,需要将字符串的一个双引号 替换为 两个双引号。并且需要在字符串的前后加上双引号
            if (srcStr.Contains("\""))
            {
                srcStr = srcStr.Replace("\"", "\"\"");
                srcStr = "\"" + srcStr + "\"";
                quoteFlag = true;
            }
            //如果只存在逗号(不存在引号),将前后加引号即可
            if (srcStr.Contains(",") && !quoteFlag)
            {
                srcStr = "\"" + srcStr + "\"";
            }
            return srcStr;
        }
    }
}

运行效果如图:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1509556.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SQL 多表查询

文章目录 多表查询的分类等值连接非等值连接自连接非自连接内连接外连接左外连接右外连接满外连接 SQL连接 JOINSQL99 语法新特性 自然连接 NATURAL JOIN & USING 多表查询的分类 等值连接 VS 非等值连接自连接 VS 非自连接内连接 VS 外连接 等值连接 关联的表有连接字段…

2.4_4 死锁的检测和解除

文章目录 2.4_4 死锁的检测和解除&#xff08;一&#xff09;死锁的检测&#xff08;二&#xff09;死锁的解除 总结 2.4_4 死锁的检测和解除 如果系统中既不采取预防死锁的措施&#xff0c;也不采取避免死锁的措施&#xff0c;系统就很可能发生死锁。在这种情况下&#xff0c;…

CrossOver24软件免费电脑虚拟机,快速在Mac和Linux上运行Windows软件

当然&#xff0c;除了之前提到的核心技术、兼容性和性能优化外&#xff0c;CrossOver2024还具有其他一些值得关注的性能特点&#xff1a; CrossOver Mac-安装包下载如下&#xff1a;https://wm.makeding.com/iclk/?zoneid50028 CrossOver linux-安装包下载如下&#xff1a;ht…

信息系统项目管理师--质量管理

国际标准化组织(ISo) 对质量 (Quality) 的定义是:“反映实体满⾜主体明确和隐含需求的能⼒的特性总和”。 国家标准对质量的定义为:“⼀组固有特性满⾜要求的程度”。固有特性是指在某事或某物中本来就有的, 尤其是那种永久的可区分的特征。对产品来说, 例如⽔泥的化学成分、强…

设计模式九:装饰器模式

文章目录 1、装饰器模式2、示例3、装饰器模式与适配器模式4、装饰器模式和代理模式5、java io流的装饰器模式 1、装饰器模式 装饰器模式&#xff08;Decorator Pattern&#xff09;允许向一个现有的对象添加新的功能&#xff0c;同时又不改变其结构。这种类型的设计模式属于结构…

大数据开发-Hive介绍以及安装配置

文章目录 数据库和数据仓库的区别Hive安装配置Hive使用方式Hive日志配置 数据库和数据仓库的区别 数据库&#xff1a;传统的关系型数据库主要应用在基本的事务处理&#xff0c;比如交易&#xff0c;支持增删改查数据仓库&#xff1a;主要做一些复杂的分析操作&#xff0c;侧重…

WPF(2)命令绑定

效果是&#xff1a;当TextBox控件的Text属性为空时show按钮不可用&#xff0c;有值时show按钮可用 项目结构 界面代码 <Window x:Class"WpfApp1.MainWindow"xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x"http://sc…

普发Pfeiffer Prisma QMS200四极质谱计内部电路图装配3D图电路板接口详细注解

普发Pfeiffer Prisma QMS200四极质谱计内部电路图装配3D图电路板接口详细注解

面向对象(精髓)变继承关系为组和关系(_Decorator模式)

在软件开发中&#xff0c;设计模式是解决常见问题的可重用解决方案。在面向对象编程中&#xff0c;继承和组合是两种常用的代码复用方式。然而&#xff0c;随着软件需求的不断变化&#xff0c;我们需要更灵活的设计方式来应对不断变化的需求。在本文中&#xff0c;我们将讨论从…

全面的 DevSecOps 指南:有效保护 CI/CD 管道的关键注意事项

数字化转型时代带来了对更快、更高效、更安全的软件开发流程的需求。DevSecOps&#xff1a;一种将安全实践集成到 DevOps 流程中的理念&#xff0c;旨在将安全性嵌入到开发生命周期的每个阶段 - 从代码编写到生产中的应用程序部署。DevSecOps 的结合可以带来许多好处&#xff0…

程序人生 - 爬虫者,教育也!

作为一个站长&#xff0c;你是不是对爬虫不胜其烦&#xff1f;爬虫天天来爬&#xff0c;速度又快&#xff0c;频率又高&#xff0c;服务器的大量资源被白白浪费。 看这篇文章的你有福了&#xff0c;我们今天一起来报复一下爬虫&#xff0c;直接把爬虫的服务器给干死机。 本文有…

RStudio更换R语言版本

今天下载R语言用于读取.xlsx文件的readxl包时&#xff0c;RStudio提示该包是使用R-4.3.3版本构建&#xff0c;而我现在使用的是R-4.3.2版本&#xff0c;所以需要升级一下R语言版本&#xff0c;这里先下载最新版本的R语言&#xff0c; 下载地址&#xff1a;The Comprehensive R…

HTML 学习笔记 总结

总结 【标签按照功能进行分类】&#xff1a; <!DOCTYPE html>&#xff1a;声明为 HTML5 文档 <html>&#xff08;双标记、块标记&#xff09;&#xff1a;是 HTML 页面的根元素&#xff0c;定义 HTML 文档 <head>&#xff08;双标记、块标记&#xff09;&a…

机器学习-04-分类算法-01决策树

总结 本系列是机器学习课程的系列课程&#xff0c;主要介绍机器学习中分类算法&#xff0c;本篇为分类算法开篇与决策树部分。 本门课程的目标 完成一个特定行业的算法应用全过程&#xff1a; 懂业务会选择合适的算法数据处理算法训练算法调优算法融合 算法评估持续调优工程…

【Linux杂货铺】操作系统

目录 &#x1f308;前言&#x1f308; &#x1f4c1; 冯诺依曼体系结构 &#x1f4c2; 拓展问题&#xff1a;程序为什么要被加载到内存&#xff1f; &#x1f4c2; 主机与主机的交互 &#x1f4c1; 操作系统的概念 &#x1f4c2; 作用 &#x1f4c2; 理解“管理” &#x…

基于Python实现电商订单的数据分析

基于Python实现电商订单的数据分析 数据集&#xff1a;技术&#xff1a;功能&#xff1a;创新点&#xff1a;明确需求和目的&#xff1a; 数据集&#xff1a; 项目使用一家全球超市4年内的电商销售订单数据&#xff0c;数据集名为superstore_dataset2011-2015.csv。数据集共有…

线性代数(一)——向量基础

向量基础 1、向量和线性组合2、向量的模和点乘3、矩阵4、参考 线性代数的核心是向量的加和乘两种运算的组合&#xff0c;本篇博客为线性代数的一个引子&#xff0c;主要从向量、线性组合和矩阵逐步引出线性代数的相关知识。 1、向量和线性组合 首先介绍的是向量相关&#xff0…

使用nexus3搭建npm私有仓库

一、下载解压安装包 下载地址&#xff1a;nexus-3.66.0-02-win.zip 二、安装并运行私服 在cmd中进入到文件夹中的bin目录下运行一下命令 nexus.exe /run等几分钟启动后&#xff0c;浏览器访问&#xff1a;默认端口8081 http://127.0.0.1:8081/ #修改端口在etc文件下 nexus-…

Oracle集群ASM磁盘扩容

先通过lsblk来查看集群两端磁盘是否扩容成功 lsblk -a查看自己两边磁盘UUID是否相同(for i in 后面为磁盘sd后字母名) for i in x y z aa ab ac ad ae do echo "KERNEL\"sd*\", SUBSYSTEM\"block\", PROGRAM\"/lib/udev/scsi_id --whitelist…

javaEE4(预习第3章,做课后习题1:简答)

1、简答 &#xff08;1&#xff09;Jsp页面翻译成的Servlet类的源文件在哪里可以找到&#xff1f;servlet实例是每次请求页面都会创建一个&#xff0c;还是只有一个&#xff08;单例&#xff09;&#xff1f; tomcat工作目录下的work目录下 只有一个 页面中定义变量加和不加…