【问题标题】:How to force BusyIndicator?如何强制 BusyIndi​​cator?
【发布时间】: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;
});

但是我什么都没有!!! 我无法解决的问题在哪里?

我发现了一个类似的问题,但我没有遇到同样的问题,但在功能完成后指示器显示。

【问题讨论】:

    标签: c# wpf xaml busyindicator


    【解决方案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。)
    猜你喜欢
    • 2012-09-05
    • 1970-01-01
    • 1970-01-01
    • 2011-04-02
    • 2012-11-28
    • 2013-05-19
    • 1970-01-01
    • 1970-01-01
    • 2012-04-11
    相关资源
    最近更新 更多