【问题标题】:button content and wait cursor problems按钮内容和等待光标问题
【发布时间】:2015-02-25 23:42:05
【问题描述】:

我有一个 WPF 应用程序,其页面包含如下所示的一些代码

public partial class MyPage : Page
{
    public MyPage ()
    {
        InitializeComponent();
    }

    private void btnClose_Click(object sender, RoutedEventArgs e)
    {
        this.Cursor = Cursors.Wait;
        this.btnClose.Content = "Cancel";

        //  some long time consuming processing

        this.Cursor = Cursors.Arrow;
        this.btnClose.Content = "Close";
    }
  }

我在关闭按钮单击处理程序上做了两件事,这会导致问题。不久处理后,我将按钮上下文文本更改为取消。我还想更改整个页面的光标以等待。完成长时间处理后,我将光标状态和按钮内容设置回原来的位置。但是我面临以下两个问题。

  1. 当应用程序进行长时间运行操作时,我看不到按钮内容为取消。它只是不断地向我展示原始内容关闭。
  2. 光标仅在按钮上变为箭头。但是在页面的其余部分,我仍然得到相同的箭头光标。

任何想法如何解决这些问题?

【问题讨论】:

    标签: wpf xaml .net-4.0


    【解决方案1】:

    默认情况下,您的代码在 UI 线程上运行,因此在线程完成执行之前,不能在 UI 线程上执行任何其他操作(例如重新渲染 UI)。

    有很多方法可以在代码完成执行之前释放对 UI 线程的控制,但我发现最简单的方法是使用 Task Parallel Library 中的 Task,它可用于在单独的线程上运行代码。

    例如,

    // this runs on the main UI thread
    this.Cursor = Cursors.Wait;
    this.btnClose.Content = "Cancel";
    
    Task.Factory.StartNew(() =>
    {
        // this code runs on a background thread
    
        // some long time consuming processing
    })
    .ContinueWith((e) =>
    {
        // this code runs from the UI thread again
        this.Cursor = Cursors.Arrow;
        this.btnClose.Content = "Close";
    });
    

    需要注意的是,UI对象只能在UI线程上修改,所以我把第二次UI更新放在了任务的.ContinueWith(...)。另一种方法是使用Dispatcher 来确保代码在 UI 线程上执行。如果您决定需要它,并且无法通过 Google 找到简单的示例,请告诉我,我会在这里写一个。

    【讨论】:

      【解决方案2】:

      这在某些地方必须是重复的

      public class WaitCursor : IDisposable
      {
          private Cursor _previousCursor;
      
          public WaitCursor()
          {
              _previousCursor = Mouse.OverrideCursor;
      
              Mouse.OverrideCursor = Cursors.Wait;
          }
      
          #region IDisposable Members
      
          public void Dispose()
          {
              Mouse.OverrideCursor = _previousCursor;
          }
      
          #endregion
      }
      
      using (new WaitCursor())
      {
           //  long blocking operation
      }
      

      【讨论】:

      • 但是#1 没有实际意义。那是阻塞操作,所以没有机会取消。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-03-05
      • 2022-01-26
      • 2010-12-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多