2010-06-15 119 views
2

我想重用一个UserControl,并借用一些逻辑来跟踪进度。我会尽量简化一些事情。 MyWindow.xaml包含一个MyUserControl。 MyUserControl有其自己的进度指示器(正在格式化...,复制文件...等),我想在MyWindow窗体中的某处反映这一进展。但是,用户控件有一些我不太明白的逻辑。我已阅读并阅读,但我仍然不理解Dispatcher。以下是用户控件中更新进度的逻辑的摘要。Dispatcher.Invoke为什么不触发UI更新?

this.Dispatcher.Invoke(DispatcherPriority.Input, (Action)(() => 
{ 
    DAProgressIndicator = InfiniteProgress.AddNewInstanceToControl(StatusGrid, new SolidColorBrush(new Color() { A = 170, R = 128, G = 128, B = 128 }), string.Empty); 
       DAProgressIndicator.Message = MediaCardAdminRes.ActivatingCard; 
       ActivateInProgress = true; 
})); 

我以为我会很聪明,并添加事件的MyUserControl将在ActivateInProgress属性集逻辑调用。

public bool ActivateInProgress 
    { 
     get 
     { 
     return _activateInProgress; 
     } 
     set 
     { 
     _activateInProgress = value; 
     if (ActivateInProgressHandler != null) 
     { 
      ActivateInProgressHandler(value); 
     } 
     } 
    } 

我设置mywindow的构造函数下面的方法设置一个用于窗口自己的进度指示器视图模型属性中的ActivateInProgressHandler。

private void SetActivation(bool activateInProgress) 
{ 
    viewModel.ActivationInProgress = activateInProgress; 
} 

但是,窗口的进度指示不会改变。所以,我确信Dispatcher.Invoke正在做一些我不明白的事情。如果我在SetActivation方法中放置一个消息框,则会更新线程块和窗口的进度指示器。我了解基本的线程,但这个整个Dispatcher对我来说是新事物。我错过了什么?

更新:它似乎现在工作。事实证明,进展正在得到如此之快的更新,以至于它从未在屏幕上显示出来。但是,我仍然想明白为什么Dispatcher.Invoke完成了(这是我没有写入的现有代码)。为什么不按照* .xaml.cs代码的其余部分完成操作内容?

+0

如何更新窗口中的进度条?然而,它必须在一个单独的线程中完成,然后使用调度程序。 – Amsakanna 2010-06-15 06:03:27

回答

1

你最后一段提到了两次线程,这就提出了有一个或多个后台线程的可能性。但是由于您没有提到应用程序中存在哪些线程,它们是如何创建的,它们是如何交互的等等,我现在假设只有一个线程。

如果UI线程是唯一的线程,问题很明显:您的UI线程忙于运行正在进行的任务,并且不需要时间来呈现更新的UI。如果是这样的问题,这可能会解决这个问题:

viewModel.ActivationInProgress = activateInProgress; 
Dispatcher.BeginInvoke(DispatcherPriority.ApplicationIdle, 
         new Action(() => {})); 

的BeginInvoke的强制输入以上所有优先级调度操作完成当前线程继续之前。

0

分派器在队列中工作。所以可能是UI线程阻塞。您可以通过Dispatcher在队列中添加更多工作,但由于UI线程阻塞,永远不会执行。

也许试试这个:

DispatcherFrame _frame = new DispatcherFrame(); 
Dispatcher.PushFrame(_frame); 

这将使您的工作盈方的工作已经在队列中。所以UI线程将完成这项工作,然后再次阻止。

相关问题