c# winfrom DataGridView 动态UI下载功能(内含GIF图) || 循环可变化的集合 数组 datatable 等
Gif演示

分解步骤
1,使用组件DataGridView
2,使用DataSource来控制表格展示的数据来源(注意:来源需要是DataTable类型)
3,需要用到异步线程。如果是不控制数据源的话,需要使用UI安全线程;(使用Control.Invoke或Control.BeginInvoke方法)
4,DataGridView的列如果设置图片,尽量代码设置
5,DataTable类型也是可以使用LINQ的,参考:AsEnumerable
完整代码
using Newtonsoft.Json;
using Sunny.UI.Win32;
using Sunny.UI;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using WinApp.i18n;
using WinApp.Until;
using WinApp.ViewModel;
using static System.Net.Mime.MediaTypeNames;
using Microsoft.EntityFrameworkCore.Metadata.Internal;
using System.Security.Cryptography; namespace WinApp.View
{
public partial class DownloadList : UserControl
{
/// <summary>
/// 开启任务的开关(作用:禁止重复启动任务)
/// </summary>
private static bool _taskSwitch = true;
/// <summary>
/// 任务中的小开关(作用:如果被外部干涉,则进行退出执行任务内容)
/// </summary>
private static bool _taskCondition = true; public DataTable _table;
List<DownloadListDto> _mainList; public UILabel _lbNotData; public DownloadList()
{
InitializeComponent();
var mainTitle = string.Empty;
mainTitle = Language.GetLang("downloadTitle1");
mainTitle += "\r" + Language.GetLang("downloadTitle2");
this.uiPanel1.Text = mainTitle; uiDataGridView1.ColumnHeadersVisible = false;
uiDataGridView1.RowTemplate.Height = 65;
uiDataGridView1.CellBorderStyle = DataGridViewCellBorderStyle.None; _lbNotData = new UILabel();
_lbNotData.Text = "No more data available";
_lbNotData.Cursor = Cursors.Hand;
_lbNotData.TextAlign = ContentAlignment.MiddleCenter;
_lbNotData.Location = new Point(450, 50);
_lbNotData.Width = 200;
_lbNotData.Visible = false;
this.uiPanel2.Controls.Add(_lbNotData);
} private void DownloadList_Load(object sender, EventArgs e)
{
QueryData();
} public void SetCondition(bool setValue)
{
_taskCondition = setValue;
}
public async Task DownloadAllAsync()
{
if (_taskSwitch)
{
if (_table.Rows.Count <= 0)
{
UIMessageDialog.ShowMessageDialog("No more data available", UILocalize.WarningTitle, showCancelButton: false, UIStyle.Orange, false);
return;
} //已经执行,请勿重复执行;
_taskSwitch = false; foreach (DataRow row in _table.Rows)
{
row["Status"] = "2";//设置为下载中的状态
uiDataGridView1.Refresh();
} while (_table.Rows.Count > 0 && _taskCondition)
{//如果列表有数据就一直循环进行下载删除
var firstRow = _table.Rows[0];
if (firstRow == null)
{//第一个元素等于NULL
return;
} for (int j = 0; j <= 100; j++)//模拟进度条
{
if (_taskCondition)
{//如果没有暂停
await Task.Delay(10); // wait for 100 milliseconds
firstRow["DownloadProgress"] = j.ToString(); }
else
{//暂停
firstRow["Status"] = "1";
}
} if (_taskCondition)
{
// 获取当前行的数据行
var _Id = (int)firstRow["Id"];
// 使用Linq查询匹配的行
var rowsToDelete = _table.AsEnumerable().FirstOrDefault(row => row.Field<int>("Id") == _Id);
_table.Rows.Remove(rowsToDelete);
}
} //foreach (DataRow row in _table.Rows)
//{
// row["Status"] = "2"; // for (int j = 0; j <= 100; j++)
// {
// if (_taskCondition)
// {
// await Task.Delay(10); // wait for 100 milliseconds
// row["DownloadProgress"] = j.ToString();
// }
// else
// {
// row["Status"] = "1";
// }
// }
// // 获取当前行的数据行
// var _Id = (int)row["Id"];
// // 使用Linq查询匹配的行
// var rowsToDelete = _table.AsEnumerable().FirstOrDefault(row => row.Field<int>("Id") == _Id);
// _table.Rows.Remove(rowsToDelete);
//} //foreach (var item in _mainList)
//{
// item.Status = 2;
// uiDataGridView1.Refresh(); // for (int i = 0; i < 100; i++)
// {
// if (_taskCondition)
// {
// await Task.Delay(100); // wait for 100 milliseconds
// item.DownloadProgress = i.ToString();
// uiDataGridView1.Refresh();
// }
// else
// {
// item.Status = 1;
// return;
// }
// }
//} //执行完毕,则可以重新执行
_taskSwitch = true;
}
else
{
//因为此次没有执行,下次允许执行;
_taskSwitch = true;
return;
}
} public void PauseAll()
{
SetCondition(false); //获取所有已经开始的数据 var pauseList = _table.AsEnumerable().Where(row => row.Field<int>("Status") == 2);
foreach (DataRow item in pauseList)
{
item["Status"] = "1";
uiDataGridView1.Refresh();
} } public void DeleteAll()
{
SetCondition(false); // 清除所有行
_table.Clear();
uiDataGridView1.Refresh();
this.uiDataGridView1.Refresh();
} public void QueryData()
{ LoadingHelper.ShowLoadingScreen(); _mainList = new List<DownloadListDto>();
_mainList.Add(new DownloadListDto()
{
Id = 1,
Title = "A1" + Environment.NewLine + "B1",
Status = 1,
DownloadProgress = "0"
});
_mainList.Add(new DownloadListDto()
{
Id = 2,
Title = "A2" + Environment.NewLine + "B2",
Status = 1,
DownloadProgress = "0"
});
_mainList.Add(new DownloadListDto()
{
Id = 3,
Title = "A3" + Environment.NewLine + "B3",
Status = 1,
DownloadProgress = "0"
});
_mainList.Add(new DownloadListDto()
{
Id = 4,
Title = "A4" + Environment.NewLine + "B4",
Status = 1,
DownloadProgress = "0"
});
_mainList.Add(new DownloadListDto()
{
Id = 5,
Title = "A5" + Environment.NewLine + "B5",
Status = 1,
DownloadProgress = "0"
}); _table = _mainList.ToDataTable();
this.uiDataGridView1.DataSource = _table; LoadingHelper.CloseForm();
uiDataGridView1.ClearSelection();
} private void uiDataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
DataGridViewRow row = uiDataGridView1.Rows[e.RowIndex]; if (uiDataGridView1.Columns[e.ColumnIndex].Name == "clTitle")
{
if (row.Cells["clStatus"].Value is int)
{
var intStatus = (int)row.Cells["clStatus"].Value;
if (intStatus == 1)
{
row.Cells["clOpDown"].Value = FileHelper.loadImageFromLocalPath(@"FileFolder/Icon/downLoad.png");
row.Cells["clOpDelete"].Value = FileHelper.loadImageFromLocalPath(@"FileFolder/Icon/delete1.png");
}
else if (intStatus == 2)
{
row.Cells["clOpDown"].Value = FileHelper.loadImageFromLocalPath(@"FileFolder/Icon/pause.png");
row.Cells["clOpDelete"].Value = FileHelper.loadImageFromLocalPath(@"FileFolder/Icon/delete1.png");
//row.Cells["clOpDelete"].Value = null;
}
else
{
// 创建一个1x1像素的透明图像
Bitmap transparentImage = new Bitmap(1, 1);
transparentImage.SetPixel(0, 0, Color.Transparent);
row.Cells["clOpDown"].Value = transparentImage;
row.Cells["clOpDelete"].Value = transparentImage;
}
} }
} private void uiDataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
{
//uiDataGridView1.ClearSelection();
} private async void uiDataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
if (uiDataGridView1.Columns[e.ColumnIndex] is DataGridViewImageColumn && e.RowIndex >= 0)
{
// 获取当前行的数据行
var currentRow = uiDataGridView1.Rows[e.RowIndex];
var _Id = (int)currentRow.Cells["clId"].Value;
if (uiDataGridView1.Columns[e.ColumnIndex].Name == "clOpDown")
{ //var currentData = _mainList.Find(x => x.Id == _Id);
var currentData = _table.AsEnumerable().FirstOrDefault(x => x.Field<int>("Id") == _Id);
if (currentData != null)
{
if (currentData["Status"].ToString() == "1")
{//1代表 未下载 currentData["Status"] = "2";//修改图标
uiDataGridView1.Refresh(); }
else
{//2代表 正在下载 _taskCondition = false;//终止执行任务
currentData["Status"] = "1";//修改图标
uiDataGridView1.Refresh(); }
//currentData.Status = 1;
//_taskCondition = false;
//uiDataGridView1.Refresh();
}
} if (uiDataGridView1.Columns[e.ColumnIndex].Name == "clOpDelete")
{ // 使用Linq查询匹配的行
var rowsToDelete = _table.AsEnumerable().FirstOrDefault(row => row.Field<int>("Id") == _Id);
_table.Rows.Remove(rowsToDelete);
}
}
}
public void DeleteMainData(int Id)
{
var currentData = _mainList.Find(x => x.Id == Id);
if (currentData != null)
{
_mainList.Remove(currentData);
uiDataGridView1.DataSource = _mainList;
uiDataGridView1.Refresh();
}
} private void uiDataGridView1_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e)
{
uiDataGridView1.Visible = true;
_lbNotData.Visible = false;
DataGridView dataGridView = (DataGridView)sender;
if (dataGridView.Rows.Count == 0)
{
uiDataGridView1.Dock = DockStyle.None;
uiDataGridView1.Visible = false; _lbNotData.Visible = true;
}
} private void uiDataGridView1_DataError(object sender, DataGridViewDataErrorEventArgs e)
{
// 取消默认的错误处理行为
e.ThrowException = false; // 获取出错的单元格
DataGridViewCell errorCell = uiDataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex]; // 获取出错的数据
object errorValue = uiDataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].Value; // 自定义错误处理逻辑
MessageBox.Show("数据错误:" + e.Exception.Message); // 可以将出错的单元格的值重置为默认值
errorCell.Value = errorCell.DefaultNewRowValue;
}
}
}
结语
上面完整代码是.cs的代码。大家拷贝本地使用的时候需要在UI界面进行拖拉组件。本例子用的是winform SunnyUI 的框架 。框架文档在这里:文档预览 - Gitee.com
c# winfrom DataGridView 动态UI下载功能(内含GIF图) || 循环可变化的集合 数组 datatable 等的更多相关文章
- Struts2实现文件的上传与动态下载功能。
本篇主要使用Struts2实现文件的上传与动态下载功能.出于安全考虑,所以,在硬盘上存储上传的文件的时候,统一都重新命名为随机字符串.用数据库存储真实文件名与随机文件名称之间的关联. 下面的是实体类 ...
- Android - 用Fragments实现动态UI - 使用Android Support Library
Android Support Library提供了一个带有API库的JAR文件来让你可以在使用最新的Android API的同时也也已在早期版本的Android上运行.例如,Support Libr ...
- iNeedle日志下载功能问题
问题: iNeedle系统本身包含日志下载功能,主要是将web服务器中的用户访问日志按照一定条件进行筛选并下载,提供管理者分析.但是这次的测试中发现iNeedle日志下载一直会卡住,web界面显示正在 ...
- 【ASP.NET Web API教程】2.3.5 用Knockout.js创建动态UI
原文:[ASP.NET Web API教程]2.3.5 用Knockout.js创建动态UI 注:本文是[ASP.NET Web API系列教程]的一部分,如果您是第一次看本博客文章,请先看前面的内容 ...
- 【Android Developers Training】 19. 序言:通过Fragments构建动态UI
注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...
- GIF图保存下来不会动?用Folx的浏览器捕获下载功能试试!
表情包大多是GIF格式的动图,有时候使用浏览器的另存为保存完发现并不能动态播放,怎么办呢?试试Folx提供的浏览器捕获下载功能,就能将各种格式的图片,包括GIF动图的下载链接捕获下来,供进一步下载使用 ...
- Safari 下用 "location.href = filePath" 实现下载功能的诡异 bug
Safari 下的一些诡异 bug 我们已经领教一二,比如前文中说的 无痕浏览模式下使用 localStorage 的 API 就会报错.今天我们要讲的是利用 location.href = file ...
- location.href 实现点击下载功能
如果页面上要实现一个点击下载的功能,传统做法是使用一个 a 标签,然后将该标签的 href 属性地址指向下载文件在服务端的地址(相对地址或者绝对地址),比如这样: 能这样实现是因为,在浏览器地址栏输入 ...
- php实现文件上传下载功能小结
文件的上传与下载是项目中必不可少的模块,也是php最基础的模块之一,大多数php框架中都封装了关于上传和下载的功能,不过对于原生的上传下载还是需要了解一下的.基本思路是通过form表单post方式实现 ...
- JavaWeb学习记录(一)——response响应头之缓存设置与下载功能的实现
一.HTTP中常用响应头 Location: http://www.it315.org/index.jsp Server:apache tomcat Content-Encoding: gzip Co ...
随机推荐
- tomcat 服务版本内存设置
1. 安装服务,如需指定java路径,需要在service.bat 中修改, 如下图 其中 pa代表当前目录 2. 安装服务, service.bat install 服务名,如下图示例 3. 内存设 ...
- 为什么游戏行业喜欢用PolarDB
简介: PolarDB 在游戏行业的最佳实践 为什么游戏行业喜欢用PolarDB 游戏行业痛点 在我看来, 不同行业对数据库使用有巨大的差别. 比如游戏行业没有复杂的事务交易场景, 他有一个非常大的b ...
- 成中集团线下IDC迁移上云
阿里云根据成中集团业务场景入手,提供了上云方案和迁移建议,利用这套架构,保障了公司数据的安全性并且满足了公司对于备份机制的建立的基本诉求,并且降低了业务出现中断的风险. 公司介绍 成中简介: 我们公司 ...
- 慢sql治理经典案例分享
简介:菜鸟供应链金融慢sql治理已经有一段时间,自己负责的应用持续很长时间没有慢sql告警,现阶段在推进组内其他成员治理应用慢sql.这里把治理过程中的一些实践拿出来分享下. 作者 | 如期 来 ...
- [Pholcus] Go项目 Pholcus 编写静态规则文件, 0 到 1
1. 初始化项目包,go mod init [module-path] 比如:go mod init github.com/abc/efg 2. 新建一个目录放置我们编写的规则 go 文件. 3. m ...
- dotnet 读 WPF 源代码笔记 渲染层是如何将字符 GlyphRun 画出来的
从业务代码构建出来 GlyphRun 对象,在 WPF 的渲染层里,如何利用 GlyphRun 提供的数据将字符在界面呈现出来.本文将和大家聊聊从 WPF 的渲染层获取到 GlyphRun 数据,到调 ...
- WPF 简单判断主线程界面是否卡顿的方法
本文来告诉大家如何使用简单的代码判断当前的软件的 UI 线程或界面是否卡顿 在后台线程调用如下代码即可用来判断是否卡顿 private static async Task<bool> Ch ...
- Data LakeHouse_理解湖仓一体
Data Lakehouse(湖仓一体)是数据管理领域中的一种新架构范例,结合了Data Warehouse和Data Lakes的最佳特性.数据分析师和数据科学家可以在同一个数据存储中对数据进行操作 ...
- 如何阅读 Paper
前言 论文(Paper)通常是新技术.算法.编程方法或软件工具的首次公布.通过阅读论文,我们可以了解最新的技术进展,保持自己的技能和知识是最新的. 同时,论文提供了对特定主题深入理解的机会.它们通常包 ...
- sh角本操作数据库
#!/bin/bash HOST="127.0.0.1" PORT="3306" USERNAME="root" PASSWORD=&quo ...