【问题标题】:Force redraw before long running operations在长时间运行操作之前强制重绘
【发布时间】:2011-11-14 21:50:31
【问题描述】:

当你有一个按钮,然后做这样的事情:

Private Function Button_OnClick

    Button.Enabled = False

    [LONG OPERATION] 

End Function

然后按钮不会变灰,因为长操作会阻止UI线程重新绘制控件。我知道正确的设计是启动后台线程/调度程序,但有时这对于简单的操作来说太麻烦了。

那么如何强制按钮在禁用状态下重绘?我在 Button 上尝试了 .UpdateLayout() ,但没有任何效果。我还尝试了 System.Windows.Forms.DoEvents(),它在使用 WinForms 时通常可以工作,但它也没有效果。

【问题讨论】:

    标签: wpf user-interface dispatcher ui-thread


    【解决方案1】:

    以下代码将满足您的需求。但是我不会使用它。使用BackgroundWorker 类进行长时间操作。它易于使用且非常稳定。
    代码如下:

       public static void ProcessUITasks() {            
            DispatcherFrame frame = new DispatcherFrame();
            Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Background, new DispatcherOperationCallback(delegate(object parameter) {
                frame.Continue = false;
                return null;
            }), null);
            Dispatcher.PushFrame(frame);
        }
    

    Here 你会找到一个关于如何使用 BackgroundWorker 的示例。

    【讨论】:

    • 他很清楚知道但不使用 Dispatcher/Backgroundworker :)
    • @edvaldig:我已经强调不要使用它,但是我已经给了他他正在寻找的代码。我认为这不值得你给-1。如果我的代码不起作用,那么给我一个-1,但不是为了提供一些额外的建议。我认为这不公平。
    • 你说得对,我太快了,评论点赞补偿:)
    • 如果你想通过COM打开另一个应用程序,你如何使用BackgroundWorker线程(我认为应该在UI线程/STA Apartment上完成)?
    【解决方案2】:

    InvalidateVisual(); @HCL 是对的...不要这样做

    就像你说的,最好开始使用后台线程/调度程序并保持 UI 线程畅通。考虑查看来自 Microsoft 的 Reactive Extensions library 以了解高级异步 ui 编程

    【讨论】:

    • 这行不通。失效只会使要重新绘制的区域失效。然而它没有画。
    • @HCL,对我来说效果很好,请参阅函数的文档:使元素的渲染无效,并强制执行全新的布局传递。布局周期完成后调用 OnRender。
    • 你确定你的 UI 线程被阻塞了吗?我上次在.net3.5SP1下测试过。在这个时候它没有工作。如果它现在可以工作,那么他们一定已经用 4.0 改变了行为。然而,这对我来说是一个很大的惊喜。
    • 响应式是否解决了应该在 UI 线程(STA 单元)上完成的 COM 上长时间操作的问题?
    【解决方案3】:

    在 Windows.Forms 中,您可以Button.Refresh()

    在 Windows.Forms 或 WPF 中,您可以让消息泵让其重绘。 Async/Await 旨在让您在没有 HCL 答案的情况下执行此操作。

    Private Async Function Button_OnClick
    
        Button.Enabled = False
    
        Await Task.Yield
    
        [LONG OPERATION] 
    
    End Function
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-11-12
      • 2011-05-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-10
      • 2019-08-03
      相关资源
      最近更新 更多