c#如何从其他类

时间:2015-09-17 18:13:26

标签: c# winforms label progress-bar

所以我试图从另一个类而不是Form类更改WinForms项目中的文本。 它应该像这样工作:

right

但它改为:

wrong

我以前的方式是将对象作为参数传递给我的其他类,从其他类我可以更改文本。我对进度条做了同样的事情,它确实在那里工作,所以它与进度条一起工作但不是标签很奇怪。

我使用此方法更改进度条:

public void IncreaseProgress(int progBarStepSize, String statusMsg, int currentProject=-1) {
   if (currentProject != -1) {
      lblStatus.Text = String.Format("Status: {0} | project {1} of {2}",statusMsg,currentProject,ProjectCount);
   }
   else {
      lblStatus.Text = String.Format("Status: {0}",statusMsg);
   }

   pb.Increment(progBarStepSize);
}

以下是我使用该方法的地方:

public void InitialiseFile(List<string> filePaths, int eurojobType)
{
    foreach (string sheet in outputSheets) {
        switch (sheet) {
            case "Summary":
                for (int i = 0; i < filePaths.Count; i++) {
                            var filePath = filePaths[i];
                    IncreaseProgress(1, "Reading Summary", i);
                    worksheetIn = excelReader.ReadExcelSummary(filePath);

                    IncreaseProgress(1, "Writing Summary", i);
                    excelWriter.WriteExcelSummary(worksheetIn);
                }
                break;
            case "Monthly_Cat1":
                for (int i = 0; i < filePaths.Count; i++) {
                    var filePath = filePaths[i];
                    IncreaseProgress(1, "Reading Monthly", i);
                    worksheetIn = excelReader.ReadExcelMonthly(filePath);

                    IncreaseProgress(1, "Writing Monthly", i);
                    excelWriter.WriteExcelMonthly(worksheetIn);
                }
                break;
        }
    }
    IncreaseProgress(1, "Completed!");
}

现在我知道这段代码有效,因为进度条增加了。并且它应该跳转到第一个if循环,因为i作为参数传递,永远不会-1

//manager class
private Label lblStatus;
private ProgressBar pb;

public Manager(ProgressBar pb, Label lbl){
    this.pb = pb;
    lblStatus = lbl;
}

//Form class
Manager mgr = new Manager(progressBar1, lblStatus, projectFilePaths.Count, outputSheets.ToArray(), exportPath);
mgr.InitialiseFile(projectFilePaths, eurjobType);

1 个答案:

答案 0 :(得分:1)

设置lblStatus.Refresh();后,您可以调用Text强制重绘控件。 但是考虑一下Slaks的评论:

  

不要在UI线程上进行阻止工作

您可以考虑使用BackgroundWorker或Task.Run或async / await模式。

举个例子:

private async void button1_Click(object sender, EventArgs e)
{
    await Task.Run(() =>
    {
        for (int i = 0; i < 10000; i++)
        {
            this.Invoke(new Action(() =>
            {
                label1.Text = i.ToString();
                label1.Refresh();
            }));
        }
    });
}

这样数字会增加,标签会刷新并显示新值,而用户界面则会响应,例如您可以移动表单或点击其他按钮。

您应该将您的UI相关代码放在Invoke触发的操作中,以防止接收跨线程操作异常。