c# - Dispatcher.BeginInvoke(new...ProgressBarProcess.Value = 1 没有显示?
问题描述
这适用于 Windows 10、Windows 应用程序 WPF .NET 框架 4.7.2
我有来自旧 Windows 窗体项目(与 2017 社区)的代码,用于运行良好的 ProgressBar(Windows 窗体项目)。我现在有一个工作正常的 wpf windows 项目,但我想为两个按钮(处理和插入按钮)单击事件添加一个进度条,因为它们需要几秒钟才能完成,我想看到一些进展。该项目仅供我使用,它始终在 Visual Studio(社区 2019)内运行。我将旧代码复制到新项目中,但进度条没有显示或显示进度。代码在旧项目的 buttonclick 事件中与新项目一样,但没有运气......我可能从旧项目中遗漏了一些东西,但我看不到什么。我知道“无法从调用线程修改 UI”,但我认为我在 Task.Factory.StartNew 中使用了不同的线程。Dispatcher.BeginInvoke 这里有很多帖子/主题,但我找不到与我的类似的帖子/主题...其中一个说这种方法是错误的方法。我不做 MVVM 的东西。我不经常做 Windows 编程 C#,所以不要以为我知道我在做什么......哈哈。任何帮助显示进度条将不胜感激。关于如何“正确”做的指针也很感激。谢谢。这是其中一个按钮 (ProcessButton_Click) 的代码,其进度条名为“ProgressBarProcess”:任何帮助显示进度条将不胜感激。关于如何“正确”做的指针也很感激。谢谢。这是其中一个按钮 (ProcessButton_Click) 的代码,其进度条名为“ProgressBarProcess”:任何帮助显示进度条将不胜感激。关于如何“正确”做的指针也很感激。谢谢。这是其中一个按钮 (ProcessButton_Click) 的代码,其进度条名为“ProgressBarProcess”:
private void ProcessButton_Click(object sender, RoutedEventArgs e)
{
if (targetBOMTextBox.Text.Length != 11)
{
MessageBox.Show("Target BOM part number missing or incorrect format.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
return;
}
Task.Factory.StartNew(() => ProcessButtonFunction());
}
private void ProcessButtonFunction()
{
ProgressBarProcess.Minimum = 1;
ProgressBarProcess.Maximum = 5;
Dispatcher.BeginInvoke(new Action(delegate () { ProgressBarProcess.Visibility = Visibility.Visible; }));
Dispatcher.BeginInvoke(new Action(delegate () { ProgressBarProcess.Value = 1; }));
fillExcelLists();
Dispatcher.BeginInvoke(new Action(delegate () { ProgressBarProcess.Value = 2; }));
convertTofloatList();
Dispatcher.BeginInvoke(new Action(delegate () { ProgressBarProcess.Value = 3; }));
splitDesignatorList();
Dispatcher.BeginInvoke(new Action(delegate () { ProgressBarProcess.Value = 4; }));
fillRecordsList();
Dispatcher.BeginInvoke(new Action(delegate () { ProgressBarProcess.Value = 5; }));
insertButton.IsEnabled = true;
clearButton.IsEnabled = true;
}
private void fillExcelLists()
{
ExcelAccess ExcelAccessOBJ = new ExcelAccess();
//get part numbers from excel column to GlobalData.excelPartNoList
ExcelAccessOBJ.ExcelReadColumn(partNoComboBox.SelectedItem.ToString(), Convert.ToInt16(dataStartRowTextBox.Text), Convert.ToInt16(dataEndRowTextBox.Text), GlobalData.excelPartNoList);
//get quantities from excel column to GlobalData.excelQuantityList
ExcelAccessOBJ.ExcelReadColumn(quantityComboBox.SelectedItem.ToString(), Convert.ToInt16(dataStartRowTextBox.Text), Convert.ToInt16(dataEndRowTextBox.Text), GlobalData.excelQuantityList);
//get designators from excel column to GlobalData.excelDesignatorList
ExcelAccessOBJ.ExcelReadColumn(designatorsComboBox.SelectedItem.ToString(), Convert.ToInt16(dataStartRowTextBox.Text), Convert.ToInt16(dataEndRowTextBox.Text), GlobalData.excelDesignatorList);
}
public class ExcelAccess
{
public void ExcelReadColumn(string column, int rowStart, int rowEnd, List<String> saveData)
{
//set up excel stuff
Microsoft.Office.Interop.Excel.Application ExcelObj = new Microsoft.Office.Interop.Excel.Application();
Microsoft.Office.Interop.Excel.Workbook theWorkbook = ExcelObj.Workbooks.Open(GlobalData.excelFilenameAndPath, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
Microsoft.Office.Interop.Excel.Sheets sheets = theWorkbook.Worksheets;
Microsoft.Office.Interop.Excel.Range data_range;
Microsoft.Office.Interop.Excel.Worksheet sheet = (Microsoft.Office.Interop.Excel.Worksheet)sheets.get_Item(1); //first sheet
//Read column
for (int i = rowStart; i <= rowEnd; i++)
{
data_range = sheet.get_Range(column + i.ToString(), column + i.ToString()); //read part number from excel sheet
//Convert cell value to string
string tempString = Convert.ToString(data_range.Cells.Value2);
if (tempString != string.Empty)
{
saveData.Add(tempString);
}
}
theWorkbook.Close();
ExcelObj.Quit();
}
}
解决方案
留在调度程序线程上并等待在后台线程上执行长时间运行的方法的任务:
private async void ProcessButton_Click(object sender, RoutedEventArgs e)
{
if (targetBOMTextBox.Text.Length != 11)
{
MessageBox.Show("Target BOM part number missing or incorrect format.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
return;
}
ProgressBarProcess.Visibility = Visibility.Visible;
ProgressBarProcess.Minimum = 1;
ProgressBarProcess.Maximum = 5;
ProgressBarProcess.Value = 1;
await Task.Run(() => fillExcelLists());
ProgressBarProcess.Value = 2;
await Task.Run(() => convertTofloatList());
ProgressBarProcess.Value = 3;
await Task.Run(() => splitDesignatorList());
ProgressBarProcess.Value = 4;
await Task.Run(() => fillRecordsList());
ProgressBarProcess.Value = 5;
insertButton.IsEnabled = true;
clearButton.IsEnabled = true;
}
不需要真正让调度员参与进来。