2012-12-18 40 views
1

我有一个标准的WPF MainWindow类,我想要显示一个消息框使用System.Windows.MessageBox,得到用户的响应,然后运行长时间运行(通过致电Sleep(...)进行模拟)。我想在操作前将光标设置为Cursors.Wait,并在结束时恢复正常。这是我得到的:MessageBox.Show导致光标不被拾取

public partial class MainWindow : Window 
{ 
    public MainWindow() 
    { 
     InitializeComponent(); 
    } 

    private void ui_button_Click(object sender, RoutedEventArgs e) 
    { 
     if (MessageBox.Show("Do you want to change the background?", "Change background", MessageBoxButton.YesNo) == MessageBoxResult.No) 
     { 
      return; 
     } 

     Cursor = Cursors.Wait; 

     Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(() => 
      { 
       System.Threading.Thread.Sleep(1500); 

       if (Background != Brushes.Green) 
       { 
        Background = Brushes.Green; 
       } 
       else 
       { 
        Background = Brushes.White; 
       } 
       Cursor = Cursors.Arrow; 
      })); 
    } 
} 

这不起作用:游标永远不会显示为等待游标。但是,如果我注释掉MessageBox这一行,它的确行得通。这里发生了什么,我如何才能使其按预期工作?

+2

尝试'Mouse.OverrideCursor = Cursors.Wait;' –

回答

4

下面的代码对我的作品:不是

Cursor = Cursors.Wait; 

试试这个:

Mouse.OverrideCursor = Cursors.Wait; 
Mouse.UpdateCursor(); 

您关闭等待光标相反的方式:

Mouse.OverrideCursor = null; 
Mouse.UpdateCursor(); 
+0

这适用于我问我问的问题,谢谢。上面的代码是使用绑定来设置Cursor的生产代码的简化版本,所以我将不得不看看我能否得到这个解决方案来处理我的实际代码。 – markmuetz

+0

我不知道有关'Mouse.OverrideCursor'。正如它发生的那样,这正是我所期待的。它比我现在的解决方案效果更好,我现在将交换使用它。 – markmuetz

+1

但我也会去后台线程。 UI线程上的长时间运行操作会使您的应用程序在执行时无响应。 – metalheart

0

尝试

DialogResult dialogResult = MessageBox.Show("Do you want to change the background?", "Change background", MessageBoxButtons.YesNo); 
if (dialogResult == DialogResult.No) 
{ 
    return; 
} 

,而不是

if (MessageBox.Show("Do you want to change the background?", "Change background", MessageBoxButton.YesNo) == MessageBoxResult.No) 
+1

那真的不应该有什么区别? – Svish

+0

@Svish:你说得对,这没什么区别。尽管如此,我已经准备好了。另外,它应该是一个'MessageBoxResult'而不是'DialogResult'。 – markmuetz

+0

多数民众赞成我是如何得到对话结果..我想你的if语句可能是错误的导致函数返回在每种情况下。但我也是C#的初学者。我希望任何人都可以帮助你解决你的问题 –

1

您运行在相同的UI线程的光标变化背景变化。确定它忙于睡眠,因此它不会显示光标变化。只要举例说明(有几个线程),一切都会好的!

private void ui_button_Click(object sender, RoutedEventArgs e) 
    { 
    if (MessageBox.Show("Do you want to change the background?", "Change background", MessageBoxButton.YesNo) == MessageBoxResult.No) 
    { 
     return; 
    } 

    Cursor = Cursors.Wait; 

    BackgroundWorker bw = new BackgroundWorker(); 
    bw.DoWork += BwOnDoWork; 
    bw.RunWorkerCompleted += BwOnRunWorkerCompleted; 
    bw.RunWorkerAsync(); 
    } 

    private void BwOnRunWorkerCompleted(object sender, RunWorkerCompletedEventArgs runWorkerCompletedEventArgs) 
    { 
    if (Background != Brushes.Green) 
    { 
     Background = Brushes.Green; 
    } 
    else 
    { 
     Background = Brushes.White; 
    } 
    Cursor = Cursors.Arrow; 
    } 

    private void BwOnDoWork(object sender, DoWorkEventArgs doWorkEventArgs) 
    { 
    System.Threading.Thread.Sleep(1500); 
    } 
+0

这也适用。不知道你的解释,但在原始问题中,在睡眠开始之前不应该改变光标吗?为什么如果你注释掉'MessageBox'这行呢?尽管如此,我可能会最终回答这个问题。 – markmuetz

+1

理论上,UI线程忙于睡眠,因此它不会更新UI和光标。我不知道为什么有时间没有使用MessageBox进行更新。我也想知道答案。 – icebat

0

尝试把你想要的代码在其它线程中运行

 ThreadPool.QueueUserWorkItem(delegate 
    { 
     //your code here... 
    });