【问题标题】:Why does my busy indicator work when I click but not for the default button?为什么当我单击时我的忙碌指示器工作但默认按钮不工作?
【发布时间】:2010-09-16 14:54:57
【问题描述】:

很难用一行来描述问题,所以这里是细节。

我之前问过一个问题,即在执行一些长时间运行的操作时在 WPF 窗口中显示繁忙指示器。原问题是here

我遵循了一条评论中的一些建议,该评论提出了一种“DoEvents”风格的解决方法。我知道这并不理想,但我只有几个小时可以将繁忙指示器添加到大约 50 个窗口,而且它们在 UI 线程上都有很多代码,我没有时间修改以使用后台线程(我希望整晚都在整理它,而不会带来额外的头痛)。

因此,在我的视图模型中设置“忙碌”属性后,我运行以下 DoEvents 样式代码:

Application.Current.Dispatcher.Invoke(DispatcherPriority.Background, new Action(delegate {  }));

现在,当我单击启动长时间运行进程的按钮时,等待指示符会根据我的需要出现,一切正常。但是,有问题的按钮是窗口中的默认按钮。如果我按 Enter 键,将使用相同的命令绑定,并且我可以在调试模式下看到以完全相同的方式访问代码。但是,忙碌指示符不显示。

谁能提出一个解决方法,让我今晚可以睡一觉?

【问题讨论】:

    标签: wpf


    【解决方案1】:

    如果您接受使用“标准”Windows 等待光标,您只需在开始操作时将 Window 的 Cursor 属性设置为 Cursors.Wait,然后在长时间运行的操作结束时设置为 null(或使用Mouse.OverrideCursor)。

    我将它包装在 IDisposable 类中:

    /// <summary>
    /// Helper to display a wainting cursor for the whole application
    /// </summary>
    public class WaitingCursor : IDisposable {
    
    private Cursor m_currentCursor;
    
    public WaitingCursor() {
    
        Enable();
    }
    
    /// <summary>
    /// Sets the cursort to the waiting cursor
    /// </summary>
    public void Enable() {
    
        m_currentCursor = Mouse.OverrideCursor;
        Mouse.OverrideCursor = Cursors.Wait;
    }
    
    /// <summary>
    /// Restores the cursor to the default one
    /// </summary>
    public void Disable() {
        Mouse.OverrideCursor = m_currentCursor;
    }
    
    #region Implementation of IDisposable
    
    /// <summary>
    /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
    /// </summary>
    public void Dispose() {
        Disable();
    }
    
    #endregion
    

    }

    那么,我们可以简单地写:

    using (new WaitingCursor()) {
    
       ... // long-running op
    }
    

    【讨论】:

    • 试一试。 Annoyingly 也有类似的问题。如果我点击按钮,一切都很好。我是否按 Enter 键,有时会起作用,有时光标在窗口边界内时消失。
    • ...奇怪的是,当我使用它时,NUnit 给了我错误,“调用线程必须是 STA,因为许多 UI 组件都需要这个”
    • 第二个问题是 Mouse.OverrideCursor 属性需要 STA 线程。在测试模式下不得不放弃这一点。
    • 对于您的问题,我深表歉意。你一定有一些非常特殊的要求,因为我在几个项目中使用过这个类,没有任何问题。据我所知,任何 GUI 项目都需要 STA。
    • 使用这种方法来模拟静态鼠标属性。请参阅ayende.com/blog/3408/dealing-with-time-in-tests - 它用于模拟 DateTime.Now,但可以使用相同的方式模拟 Mouse.OverrideCursor 属性设置器。
    猜你喜欢
    • 2012-07-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-19
    • 1970-01-01
    • 2018-02-10
    • 2019-01-29
    • 2011-09-24
    相关资源
    最近更新 更多