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 等的更多相关文章

  1. Struts2实现文件的上传与动态下载功能。

    本篇主要使用Struts2实现文件的上传与动态下载功能.出于安全考虑,所以,在硬盘上存储上传的文件的时候,统一都重新命名为随机字符串.用数据库存储真实文件名与随机文件名称之间的关联. 下面的是实体类 ...

  2. Android - 用Fragments实现动态UI - 使用Android Support Library

    Android Support Library提供了一个带有API库的JAR文件来让你可以在使用最新的Android API的同时也也已在早期版本的Android上运行.例如,Support Libr ...

  3. iNeedle日志下载功能问题

    问题: iNeedle系统本身包含日志下载功能,主要是将web服务器中的用户访问日志按照一定条件进行筛选并下载,提供管理者分析.但是这次的测试中发现iNeedle日志下载一直会卡住,web界面显示正在 ...

  4. 【ASP.NET Web API教程】2.3.5 用Knockout.js创建动态UI

    原文:[ASP.NET Web API教程]2.3.5 用Knockout.js创建动态UI 注:本文是[ASP.NET Web API系列教程]的一部分,如果您是第一次看本博客文章,请先看前面的内容 ...

  5. 【Android Developers Training】 19. 序言:通过Fragments构建动态UI

    注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...

  6. GIF图保存下来不会动?用Folx的浏览器捕获下载功能试试!

    表情包大多是GIF格式的动图,有时候使用浏览器的另存为保存完发现并不能动态播放,怎么办呢?试试Folx提供的浏览器捕获下载功能,就能将各种格式的图片,包括GIF动图的下载链接捕获下来,供进一步下载使用 ...

  7. Safari 下用 "location.href = filePath" 实现下载功能的诡异 bug

    Safari 下的一些诡异 bug 我们已经领教一二,比如前文中说的 无痕浏览模式下使用 localStorage 的 API 就会报错.今天我们要讲的是利用 location.href = file ...

  8. location.href 实现点击下载功能

    如果页面上要实现一个点击下载的功能,传统做法是使用一个 a 标签,然后将该标签的 href 属性地址指向下载文件在服务端的地址(相对地址或者绝对地址),比如这样: 能这样实现是因为,在浏览器地址栏输入 ...

  9. php实现文件上传下载功能小结

    文件的上传与下载是项目中必不可少的模块,也是php最基础的模块之一,大多数php框架中都封装了关于上传和下载的功能,不过对于原生的上传下载还是需要了解一下的.基本思路是通过form表单post方式实现 ...

  10. JavaWeb学习记录(一)——response响应头之缓存设置与下载功能的实现

    一.HTTP中常用响应头 Location: http://www.it315.org/index.jsp Server:apache tomcat Content-Encoding: gzip Co ...

随机推荐

  1. 顺通鞋服进销存OA管理系统

    鞋服进销存OA管理系统通过十几年的积淀与创新,顺通与众多鞋服企业一起共创,形成了涵盖协同办公.移动办公.知识管理.数据运营.多维门户等领域,以鞋服新品研发管理.生产排班管理.门店一体化管理.市场费用管 ...

  2. Memory Error

    不久前,为了满足工作中日常的各种实验测试需求,终于按需求组装一台塔式的server T440.但是没有多久就出现些问题,以下大概是问题和现象简单描述: (1). 最开始时,没几天就出现自动重启的问题, ...

  3. 力扣1098(MySQL)-小众书籍(中等)

    题目: 书籍表 Books: book_id 是这个表的主键 订单表 Orders: order_id 是这个表的主键.book_id 是 Books 表的外键. 问题你需要写一段 SQL 命令,筛选 ...

  4. 力扣534(MySQL)-游戏玩法分析Ⅲ(中等)

    题目: 需求:请编写一个 SQL 查询,同时报告每组玩家和日期,以及玩家到目前为止玩了多少游戏.也就是说,在此日期之前玩家所玩的游戏总数.详细情况请查看示例. 查询结果格式在以下示例中: 对于 ID ...

  5. 力扣273(java)-整数转换英文表示(困难)

    题目: 将非负整数 num 转换为其对应的英文表示. 示例 1: 输入:num = 123输出:"One Hundred Twenty Three"示例 2: 输入:num = 1 ...

  6. 基于 Flink CDC 实现海量数据的实时同步和转换

    简介: 徐榜江在 5.21 Flink CDC Meetup 的分享. 摘要:本文整理自 Apache Flink Committer,Flink CDC Maintainer,阿里巴巴高级开发工程师 ...

  7. 性能提升 57% ,SMC-R 透明加速 TCP 实战解析 | 龙蜥技术

    ​简介:SMC-R 是如何加速 TCP 应用? 编者按:TCP 协议作为当前使用最为广泛的网络协议,场景遍布移动通信.数据中心等.对于数据中心场景,通过弹性 RDMA 实现高性能网络协议 SMC-R, ...

  8. MAE 自监督算法介绍和基于 EasyCV 的复现

    ​简介:自监督学习(Self-Supervised Learning)能利用大量无标注的数据进行表征学习,然后在特定下游任务上对参数进行微调.通过这样的方式,能够在较少有标注数据上取得优于有监督学习方 ...

  9. 达摩院重要科技突破!空天数据库引擎Ganos解读

    简介: Ganos空天数据库引擎是李飞飞带领的达摩院数据库与存储实验室研发的新一代位置智能引擎,采用了平台即服务.多模融合.计算下推和云原生全新处理架构,为政府.企事业单位.泛互联网客户提供移动对象. ...

  10. dotnet 启动进程传入不存在的文件夹作为工作目录行为变更

    本文记录在 dotnet 下,启动进程,传入不存在的文件夹作为进程的工作目录,分别在 .NET Framework 和 .NET Core 的行为 在 dotnet 6 下,可以使用 ProcessS ...