当前位置: 首页 > article >正文

c# winfrom增加进度条

1. 在窗体上添加一个 ProgressBar 控件

在您的窗体中添加一个 ProgressBar 控件,并设置其属性为 Marquee 或 Continuous。这个控件用来展示连接测试的进度。

2. 初始化 BackgroundWorker

在窗体的构造函数中,初始化并配置 BackgroundWorker。假设您的窗体类名为 Form1

BackgroundWorker backgroundWorker;  

public Form1() // 构造函数  
{  
    InitializeComponent()

    // 具体原因看问题点1 
    System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;

    // 初始化 BackgroundWorker  
    backgroundWorker = new BackgroundWorker();  
    backgroundWorker.WorkerReportsProgress = true;  
    backgroundWorker.DoWork += BackgroundWorker_DoWork;  
    backgroundWorker.ProgressChanged += BackgroundWorker_ProgressChanged;  
    backgroundWorker.RunWorkerCompleted += BackgroundWorker_RunWorkerCompleted;  
}

3. 开始 BackgroundWorker

在 btnTestLink_Click 方法中启动 BackgroundWorker,并显示进度条:

private void btnTestLink_Click(object sender, EventArgs e)  
{  
    if (!backgroundWorker.IsBusy)  
    {  
        progressBar.Visible = true; // 显示进度条  
        progressBar.Value = 0; // 重置进度条  
        backgroundWorker.RunWorkerAsync(); // 启动异步操作  
    }  
}

4. 执行连接操作和报告进度

在 BackgroundWorker_DoWork 方法中实现您的连接逻辑。当每个项目完成连接测试后,通过 ReportProgress 方法更新进度:

private void BackgroundWorker_DoWork(object sender, DoWorkEventArgs e)  
{  
    int totalItems = lvDevice.Items.Count;  
    int completedItems = 0;  
    
    foreach (ListViewItem item in lvDevice.Items)  
    {  
        if (item.Checked)  
        {  
            cp.IP = item.SubItems[3].Text;  
            cp.IPPort = Int32.Parse(item.SubItems[4].Text);  
            cp.CommStyle = 1;  
            cp.ClockID = Int32.Parse(item.SubItems[0].Text);  
            bool isConnected = OpenPort(ref cp);  
            
            // 创建一个更新对象  
            var updateInfo = new  
            {  
                Item = item,  
                Success = isConnected  
            };  

            // 报告进度  
            backgroundWorker.ReportProgress(0, updateInfo);  
            
            ClosePort(ref cp);  
            completedItems++;  
            
            // 更新进度条的值  
            backgroundWorker.ReportProgress((completedItems * 100) / totalItems);  
        }  
    }  
}

5. 更新 UI 元素

在 ProgressChanged 方法中根据连接结果更新 UI 控件:

private void BackgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)  
{  
    var updateInfo = (dynamic)e.UserState;  
    
    // 更新 ListView 项的状态  
    if (updateInfo.Success)  
    {  
        updateInfo.Item.BackColor = Color.GreenYellow; // 成功则设置为绿色  
        updateInfo.Item.SubItems[5].Text = "连接成功"; // 显示连接状态  
        updateInfo.Item.ForeColor = Color.Black; // 设置文本颜色为黑色  
        updateInfo.Item.SubItems[5].ForeColor = Color.Green; // 状态文本颜色为绿色  
    }  
    else  
    {  
        updateInfo.Item.BackColor = Color.Red; // 失败则设置为红色  
        updateInfo.Item.SubItems[5].Text = "连接失败"; // 显示连接状态  
        updateInfo.Item.ForeColor = Color.Black; // 设置文本颜色为黑色  
        updateInfo.Item.SubItems[5].ForeColor = Color.Red; // 状态文本颜色为红色  
    }  
}

6. 处理完成操作

在 RunWorkerCompleted 方法中隐藏进度条,并提示用户所有操作已完成:private void BackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)  
{  
    progressBar.Visible = false; // 隐藏进度条  
    MessageBox.Show("所有连接测试完成!");  
}

问题点:

1.System.InvalidOperationException:“线程间操作无效: 从不是创建控件“lvDevice”的线程访问它

System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;

目的

System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls 是一个属性,设置为 false 后,允许从非创建控件的线程访问和修改控件。然而,尽管这样做可以消除异常,但这并不是一个好的做法,原因如下:

  1. 不安全性:直接从其他线程访问 UI 控件可能引发线程间竞争条件,导致应用程序崩溃或 UI 状态出错。
  2. 不推荐的做法:这种做法破坏了 Windows Forms 本身的线程模型,可能会导致难以调试的错误。
  3. 可维护性差:其他开发人员在看到此设置时,可能不明白代码为什么会这样处理,增加了理解和维护的复杂性。

正确的做法

正确的方式是使用 Control.Invoke 或 Control.BeginInvoke 方法将 UI 更新的代码封装进一个委托,并在主线程上执行。这样做不仅安全而且符合线程模型。


http://www.kler.cn/a/569406.html

相关文章:

  • WP 高级摘要插件:助力 WordPress 文章摘要精准自定义显示
  • Python Cookbook-2.13 使用C++的类iostream语法
  • 解决 Dell PowerEdge T630 增加第三方 PCIe 设备后制冷系统异常
  • 【深度学习】Hopfield网络:模拟联想记忆
  • JAVA调用Deepseek的api,完成基本对话
  • HTML AI 编程助手
  • Spring系列学习之Spring Messaging消息支持
  • 基于FD-MIMO技术的雷达通信一体化系统波形设计matlab模拟与仿真
  • Android应用app实现AI电话机器人接打电话
  • 如何在netlify一键部署静态网站
  • 【极客时间】浏览器工作原理与实践-2 宏观视角下的浏览器 (6讲) - 2.3 HTTP请求流程:为什么很多站点第二次打开速度会很快?
  • Python Tornado 框架面试题及参考答案
  • 计算机毕业设计Hadoop+Spark+DeepSeek-R1大模型音乐推荐系统 音乐数据分析 音乐可视化 音乐爬虫 知识图谱 大数据毕业设计
  • 视觉图像坐标转换
  • P8680 [蓝桥杯 2019 省 B] 特别数的和
  • 测试用例详解
  • 基于springboot的文旅网站系统的设计与实现
  • Linux mkdir 命令
  • DeepSeek学习规划
  • 运行程序时出现加载配置文件时出错,对路径****的访问被拒绝