2016-08-03 2 views
2

У меня есть проблема с обновлением пользовательского интерфейса в этом RelayCommand:UI нить не освежает, как ожидается, в форме WPF

private RelayCommand _DeleteReferenceCommand; 
public RelayCommand DeleteReferenceCommand 
{ 
    get 
    { 
     return _DeleteReferenceCommand ?? (_DeleteReferenceCommand = new RelayCommand(
      () => 
       { 
       //the 2 next lines trigger properties that will modify some components Visibility on the view 
       ReferencesGridWithPicsUC.TextReplacingGridView = "Deleting the reference. Please wait..."; 
       ReferencesGridWithPicsUC.GridViewVisibility = false; 
       System.Windows.Forms.Cursor.Current = System.Windows.Forms.Cursors.WaitCursor; // mouse cursor change 


       //using multi-threading so that UI updates while a long process takes place in the background 
       Task.Run(() => 
       { 
        Application.Current.Dispatcher.Invoke((new Action(() => 
        { 
        System.Threading.Thread.Sleep(3000); // simulates a long process 
        ReferencesGridWithPicsUC.GridViewVisibility = true; // Sets the UI controls visibility back to previous state 
        System.Windows.Forms.Cursor.Current = System.Windows.Forms.Cursors.Hand; // Mouse cursor back to previous value 
       } 
      ))); 
      } 
     ); 
    }, 
    () => { return ReferencesGridWithPicsUC.SelectedReference != null; } 
    )); 
    } 
} 

В частности, когда я запустить приложение и запустить этот код для Форст времени, она работает как ожидаемый (курсор мыши и элементы управления обновляются как ожидается до спящего режима (3000) и обратно к нормальному состоянию после этого. Когда код выполняется снова, я вижу, что свойство правильно обновлено GridViewVisibility. Но пользовательский интерфейс больше не обновляется: видимость, вызванная изменениями GridViewVisibility, не обновляется. С другой стороны, курсор мыши продолжает обновляться, как ожидалось ....

Если кто-то может решить эту кровавую головоломку, я буду в вашем долге;)

+2

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

ответ

4

Вы должны вызвать только Диспетчер для обновления пользовательского интерфейса.

Используйте Task.Run для задания фона.

await Task.Run(() => 
    { 
     Thread.Sleep(3000); 
    }); 

в асинхронном делегатом

new RelayCommand(
      async() => 
      { 

После этого, вы будете обратно в потоке пользовательского интерфейса, так что грузоотправитель больше не нужен.

+0

Благодарим вас за помощь. Я даже не использовал метод/команду asynch. Просто удалите Thread.Sleep (3000); от вызова диспетчера сделал трюк. –

Смежные вопросы