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. 力扣239(Java)- 滑动窗口最大值(困难)

    题目: 给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧.你只可以看到在滑动窗口内的 k 个数字.滑动窗口每次只向右移动一位. 返回 滑动窗口中的最大值 . 示 ...

  2. 安全同学讲Maven间接依赖场景的仲裁机制

    简介: 去年的Log4j-core的安全问题,再次把供应链安全推向了高潮.在供应链安全的场景,蚂蚁集团在静态代码扫描平台-STC和资产威胁透视平台-哈勃这2款产品在联合合作下,优势互补,很好的解决了直 ...

  3. DTCC 2020 | 阿里云王涛:阿里巴巴电商数据库上云实践

    简介: 第十一届中国数据库技术大会(DTCC2020),在北京隆重召开.大会以"架构革新 高效可控"为主题,重点围绕数据架构.AI与大数据.传统企业数据库实践和国产开源数据库等内容 ...

  4. 这样才是代码管理和 Commit 的正确姿势! | 研发效能提升36计

    ​简介:效能提升从小习惯开始,这样才是代码管理和 Commit 的正确姿势! ​ 专栏策划|雅纯 志愿编辑|张晟 软件交付是以代码为中心的交付过程,其中代码的作用有几点:第一,最终的制品要交付成什么样 ...

  5. Let's Fluent:更顺滑的MyBatis

    简介: 只需瞅一眼Google Trends上全球Java界最热门的两款SQL映射框架近一年的对比数字,就不难了解其实力分布:在此领域,MyBatis早已占领东亚地区开发者市场,并以绝对优势稳居中国最 ...

  6. SmartNews:基于 Flink 加速 Hive 日表生产的实践

    简介: 将 Flink 无缝地集成到以 Airflow 和 Hive 为主的批处理系统的技术挑战和应对方案. 本文介绍了 SmartNews 利用 Flink 加速 Hive 日表的生产,将 Flin ...

  7. 2019-11-29-C#-如何写-DEBUG-输出

    title author date CreateTime categories C# 如何写 DEBUG 输出 lindexi 2019-11-29 08:28:35 +0800 2018-2-13 ...

  8. docker-compose安装EFK

    一.环境 IP 系统 配置 版本 192.168.10.100 Centos7.9 2核4G Docker Compose version v2.19.1.EFK-7.17.11 EFK版本是试用版本 ...

  9. vue通过input选取图片,jq的ajax向服务器上传img

    <template>   <div class="">     <!-- 选择后预览 -->     <img v-if="im ...

  10. 经验之谈:我为什么选择了这样一个激进的缓存大Key治理方案

    一.引言 本文将结合我的一次Redis大Key的治理经验,来浅谈一下缓存大Key的治理方案选择.文中主要包括缓存大Key基础知识.大Key治理方案选择.大Key治理案例等,适合有一定开发经验的开发者阅 ...