如何强制 BusyIndi​​cator?

Posted

技术标签:

【中文标题】如何强制 BusyIndi​​cator?【英文标题】:How to force BusyIndicator? 【发布时间】:2011-10-06 19:52:42 【问题描述】:

我使用扩展的 WPF 工具包 BusyIndi​​cator

我的 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 在函数末尾显示 BusyIndi​​cator 在 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);                   
            
        
    

【讨论】:

感谢您指出显而易见的事情。严重地。 (我一直想知道为什么我的 BusyIndi​​cator 没有出现半小时。Duh。)

以上是关于如何强制 BusyIndi​​cator?的主要内容,如果未能解决你的问题,请参考以下文章

IBM Worklight:BusyIndi​​cator 未显示

找不到包含 BusyIndi​​cator 的程序集

Silverlight BusyIndi​​cator 内容禁用

消息框的 Silverlight BusyIndi​​cator 背景颜色

IBM Worklight 6.0 - 无法更改默认 WL.BusyIndi​​cator 文本

类型工具包:BusyIndi​​cator 未找到