Gif演示 分解步驟 1,使用組件DataGridView 2,使用DataSource來控製表格展示的數據來源(註意:來源需要是DataTable類型) 3,需要用到非同步線程。如果是不控制數據源的話,需要使用UI安全線程;(使用Control.Invoke或Control.BeginInvoke方 ...
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
從前慢,車馬慢。 一生只愛一個人。