C# 如何动态更新我的UI
我已经研究了几个有关动态UI的问题,但我仍然不明白我遗漏了什么。此外,我还学习了关于如何使用任务的教程,但我的理解仍然有限。以下是我想要实现的目标: 我的应用程序正在幕后进行一些工作,但我希望我的UI能够响应。我尝试了以下方法(请参见代码),但在调用dispatcher之前,UI不会开始更新。我希望UI状态为:C# 如何动态更新我的UI,c#,wpf,task,dynamic-ui,C#,Wpf,Task,Dynamic Ui,我已经研究了几个有关动态UI的问题,但我仍然不明白我遗漏了什么。此外,我还学习了关于如何使用任务的教程,但我的理解仍然有限。以下是我想要实现的目标: 我的应用程序正在幕后进行一些工作,但我希望我的UI能够响应。我尝试了以下方法(请参见代码),但在调用dispatcher之前,UI不会开始更新。我希望UI状态为: 正在创建…--单击CreatePivotTable按钮后 正在建立连接…——调用provider.GetReportData方法之前 连接成功或连接失败取决于结果 完成了 <!-
<!-- language: lang-cs -->
private void CreatePivotTableButton(object sender, RoutedEventArgs e)
{
this.StatusToBeDisplayed.Content = "Creating...";
this.DescriptionLabel.IsEnabled = false;
this.TextBlockBorder.IsEnabled = true;
List<CombinedData> items = (List<CombinedData>)CustomerComboBox.ItemsSource;
List<int> selectedItems = new List<int>();
foreach (CombinedData item in items)
{
if (item.IsSelected)
{
selectedItems.Add(item.ReferenceId);
}
}
PCTProvider provider = new PCTProvider();
ExportToExcel export = new ExportToExcel();
ExcelAutomation excelAutomation = new ExcelAutomation();
this.ResultTextBlock.Text = "Establishing Connection";
DataTable generateReportDataTable = provider.GetReportData(selectedItems);
Excel.Workbook workbook = export.ExportDataTableToExcel(generateReportDataTable);
Task updateTask = Task.Factory.StartNew(() =>
{
Dispatcher.Invoke(new Action(() => excelAutomation.CreatePivotTable(workbook)));
}).ContinueWith(result =>
{
Dispatcher.Invoke(new Action(() => this.StatusToBeDisplayed.Content = "Done!"));
Dispatcher.Invoke(new Action(() => OriginalStatus()));
}, TaskScheduler.FromCurrentSynchronizationContext());
}
私有void CreatePivotTableButton(对象发送器,RoutedEventArgs e)
{
this.StatusToBeDisplayed.Content=“创建…”;
this.DescriptionLabel.IsEnabled=false;
this.TextBlockBorder.IsEnabled=true;
列表项=(列表)CustomerComboBox.ItemsSource;
List selectedItems=新建列表();
foreach(项目中的组合数据项)
{
如果(项目.已选定)
{
选择editems.Add(item.ReferenceId);
}
}
PCTProvider provider=新PCTProvider();
ExportToExcel export=新的ExportToExcel();
ExcelAutomation=新的ExcelAutomation();
this.ResultTextBlock.Text=“建立连接”;
DataTable generateReportDataTable=provider.GetReportData(selectedItems);
Excel.Workbook工作簿=export.ExportDataTableToExcel(generateReportDataTable);
任务更新任务=Task.Factory.StartNew(()=>
{
调用(新操作(()=>excelAutomation.CreatePivotTable(工作簿));
}).ContinueWith(结果=>
{
Invoke(新操作(()=>this.StatusToBeDisplayed.Content=“Done!”);
Invoke(新操作(()=>OriginalStatus());
},TaskScheduler.FromCurrentSynchronizationContext());
}
我非常感谢你的时间和帮助 我认为您不需要与和/或可能的
任务调度器
通过在任务中执行工作,您可以让UI线程响应消息泵。
您可能希望将CreatePivotTableButton
的更多工作移到任务中
请尝试以下方法:
private void CreatePivotTableButton(object sender, RoutedEventArgs e)
{
this.StatusToBeDisplayed.Content = "Creating...";
this.DescriptionLabel.IsEnabled = false;
this.TextBlockBorder.IsEnabled = true;
// move the rest of the code into your Task to perform the work off the UI thread
Task updateTask = Task.Factory.StartNew(() =>
{
List<CombinedData> items = (List<CombinedData>)CustomerComboBox.ItemsSource;
List<int> selectedItems = new List<int>();
foreach (CombinedData item in items)
{
if (item.IsSelected)
{
selectedItems.Add(item.ReferenceId);
}
}
PCTProvider provider = new PCTProvider();
ExportToExcel export = new ExportToExcel();
ExcelAutomation excelAutomation = new ExcelAutomation();
Dispatcher.Invoke(new Action(() => this.ResultTextBlock.Text = "Establishing Connection"));
DataTable generateReportDataTable = provider.GetReportData(selectedItems);
Excel.Workbook workbook = export.ExportDataTableToExcel(generateReportDataTable);
excelAutomation.CreatePivotTable(workbook);
Dispatcher.Invoke(new Action(() => this.StatusToBeDisplayed.Content = "Done!"));
Dispatcher.Invoke(new Action(() => OriginalStatus()));
});
}
private void CreatePivotTableButton(对象发送方,RoutedEventTarget e)
{
this.StatusToBeDisplayed.Content=“创建…”;
this.DescriptionLabel.IsEnabled=false;
this.TextBlockBorder.IsEnabled=true;
//将其余的代码移到任务中,以执行UI线程之外的工作
任务更新任务=Task.Factory.StartNew(()=>
{
列表项=(列表)CustomerComboBox.ItemsSource;
List selectedItems=新建列表();
foreach(项目中的组合数据项)
{
如果(项目.已选定)
{
选择editems.Add(item.ReferenceId);
}
}
PCTProvider provider=新PCTProvider();
ExportToExcel export=新的ExportToExcel();
ExcelAutomation=新的ExcelAutomation();
Invoke(新操作(()=>this.ResultTextBlock.Text=“建立连接”);
DataTable generateReportDataTable=provider.GetReportData(selectedItems);
Excel.Workbook工作簿=export.ExportDataTableToExcel(generateReportDataTable);
excelAutomation.CreatePivotTable(工作簿);
Invoke(新操作(()=>this.StatusToBeDisplayed.Content=“Done!”);
Invoke(新操作(()=>OriginalStatus());
});
}
您可能希望将代码分解为按钮事件可以调用的较小方法。然后,在每次方法调用之前,您都要更新UI,告诉用户将要发生什么。这些将立即触发,因为它们甚至在调用真正的worker方法之前发生。如果您想将这些都放在一个方法中,那么您可以尝试使用Application.DoEvents
。这只是告诉运行时它应该休息一下,看看是否还有其他东西在等待运行(比如更新表单)。UI不应该在单击按钮后立即更新为“创建…”吗?我将用一些小方法来分解它,看看这是否有帮助。谢谢,这只是因为它是方法中的第一个,并不意味着处理器将有机会完成所涉及的实际工作。这就是doevents所做的,但使用它不再是好的实践。您可能需要研究异步编码:@Oliver您解决问题了吗?@chaddienhart再次感谢您的帮助。它就像一个符咒。关于更多的问题,我需要做什么来更新UI。换句话说,我计划添加一个文本块,我想添加描述幕后发生的事情的文本。我是否需要使用另一个Dispatcher.Invoke,还是应该创建一个处理它的新方法?再次感谢你的帮助!