如何动态更新我的UI

时间:2014-03-25 23:06:39

标签: c# wpf task dynamic-ui

我已经查看了几个与动态用户界面相关的问题,但我仍然不了解我所缺少的内容。另外,我已经关注了如何使用任务的教程,但我的理解仍然有限。以下是我想要实现的目标:

我的应用程序正在幕后做一些工作,但我希望我的UI能够响应。我尝试过以下操作(请参阅代码),但在调用调度程序之前,UI不会开始更新。我希望UI状态为:

  1. 创建... - 单击CreatePivotTableButton后立即
  2. 建立连接... - 在调用provider.GetReportData方法之前
  3. 连接成功或连接失败,具体取决于结果
  4. 完成。

     <!-- 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());
    
    }
    
  5. 我非常感谢您的时间和帮助。

1 个答案:

答案 0 :(得分:0)

我认为您不需要ContinueWith和/或TaskScheduler 通过在Task中完成工作,您可以让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()));
    });
}