如何强制 BusyIndicator?
Posted
技术标签:
【中文标题】如何强制 BusyIndicator?【英文标题】:How to force BusyIndicator? 【发布时间】:2011-10-06 19:52:42 【问题描述】:我使用扩展的 WPF 工具包 BusyIndicator
我的 Xaml
<extToolkit:BusyIndicator Name="wait" IsBusy="False" Cursor="Wait" Grid.ColumnSpan="3" Margin="10,10,10,10"/>
我的代码:
private void esp_Click(object sender, RoutedEventArgs e)
wait.IsBusy = true;
// My work here make some time to finish
wait.IsBusy = false;
但它永远不会显示,我尝试让 MessageBox 在函数末尾显示 BusyIndicator 在 MessageBox 之后显示,
我试过了
wait.Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Send,
(Action)delegate
wait.IsBusy = true;
);
但是我什么都没有!!! 我无法解决的问题在哪里?
我发现了一个类似的问题,但我没有遇到同样的问题,但在功能完成后指示器显示。
【问题讨论】:
【参考方案1】:问题是您正在调度程序的线程中执行所有工作(我假设esp_Click
是一个事件处理程序)。这实际上意味着在执行长任务时,UI 不会更新。
您需要在单独的线程中执行工作 - 创建一个新线程、使用线程池或创建一个任务。在开始之前将IsBusy
设置为true
,在完成工作之后设置为false
。从另一个线程更新wait.IsBusy
时,您需要使用Dispatcher.BeginInvoke/Invoke
。
示例代码:
private void LongRunningTask()
// your long running code
// after you complete:
Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Send,
(Action)delegate
wait.IsBusy = false;
);
private void esp_Click(object sender, RoutedEventArgs e)
wait.IsBusy = true; // either here, or in your long running task - but then remember to use dispatcher
var thread = new Thread(LongRunningTask);
thread.Start();
// OR
ThreadPool.QueueUserWorkItem(state => LongRunningState());
// OR, in .NET 4.0
Task.Factory.StartNew(LongRunningTask);
请注意,这两种解决方案都不能处理异常 - 您必须自己添加错误处理(或在最后一个示例的情况下使用任务延续)。
【讨论】:
当我必须添加 wait.IsBusy = true; !!在我的长代码之前? 我在代码中使用了一些文本框,但该文本框有一个例外“另一个线程拥有它”!! 每次从调度程序以外的任何线程访问任何 UI 元素时,您都必须使用调度程序 - 文本框、忙碌指示器、按钮等。 在 Silverlight 4 中做什么?我不能强迫被炸的东西画吗?我真的没有执行任何可以与界面隔离的处理。 :(【参考方案2】:您可以使用INotifyPropertyChanged
:
<extToolkit:BusyIndicator Name="wait" IsBusy="Binding IsBusy" Cursor="Wait" Grid.ColumnSpan="3" Margin="10,10,10,10"/>
和 C#:
/// <summary>
/// The <see cref="IsBusy" /> property's name.
/// </summary>
public const string IsBusyPropertyName = "IsBusy";
private bool _isBusy = false;
public bool IsBusy
get
return _isBusy;
set
if (_isBusy != value)
_isBusy = value;
RaisePropertyChanged(IsBusyPropertyName);
【讨论】:
感谢您指出显而易见的事情。严重地。 (我一直想知道为什么我的 BusyIndicator 没有出现半小时。Duh。)以上是关于如何强制 BusyIndicator?的主要内容,如果未能解决你的问题,请参考以下文章
IBM Worklight:BusyIndicator 未显示
Silverlight BusyIndicator 内容禁用
消息框的 Silverlight BusyIndicator 背景颜色