2014-12-29 4 views
1

У меня есть приложение 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. Когда приложение выполняет длительную работу, я не могу увидеть содержимое кнопки как Отмена. Он просто продолжает показывать мне оригинальный контент CLose.
  2. Курсор меняется на стрелку только на кнопке. Однако на остальной странице я все равно сохраняю такой же курсор.

Любые идеи о том, как решить эту проблему?

ответ

1

Ваш код не работает в потоке пользовательского интерфейса по умолчанию, так что ничего не может быть выполнена в потоке пользовательского интерфейса (например, повторное оказание пользовательского интерфейса) до тех пор, выполнение нитей завершается.

Есть много способов отпуская управление потоком UI перед кодом завершения выполнения, но я считаю, проще всего использовать Task из Task Parallel Library, который может быть использован для запуска кода в отдельном потоке.

Например,

// 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"; 
}); 

Следует отметить, что объекты пользовательского интерфейса могут быть изменены только в потоке пользовательского интерфейса, поэтому я поставил второе обновление пользовательского интерфейса в .ContinueWith(...) задачи. Альтернативой этому было бы использование Dispatcher для обеспечения выполнения кода в потоке пользовательского интерфейса. Если вы решите, что вам это нужно, и не можете найти простой пример через Google, сообщите мне, и я напишу здесь.

1

Это должно быть дубликатом, где некоторые

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 
} 
+0

спасибо. Любые мысли о №1 из моего вопроса? – BKS

+0

Но # 1 спорный. Это операция блокировки, и поэтому нет возможности отменить. – Paparazzi