2013-10-07 2 views
1

Мое приложение призмы имеет много асинхронных операций, называемых моими моделями просмотров. В некоторых случаях я хочу, чтобы представление было отключено и отображало какой-то индикатор занятости, пока модель представления не вернет результат операции async.Создание базового загрузочного представления с призмой

Хотя я создал базовый вид, который будет реализовывать это поведение (т. Е. Имеет свойство зависимостей IsLoading, которое отключит представление и отобразит над ним индикатор занятости). Проблема в том, что я не уверен, как реализовать это базовое представление. Любая помощь будет оценена, спасибо.

Редактировать: Я написал DownloadView, который выполняет эту работу, я думаю.

public class LoadingView : UserControl { private object content;

public bool IsLoading 
    { 
     get 
     { 
      return (bool)GetValue(IsLoadingProperty); 
     } 
     set 
     { 
      SetValue(IsLoadingProperty, value); 
     } 
    } 

    private ProgressRing m_RingControl; 

    public LoadingView() 
    { 
     m_RingControl = new ProgressRing(); 
     m_RingControl.IsActive = false; 
    } 

    // Using a DependencyProperty as the backing store for IsLoading. This enables animation, styling, binding, etc... 
    public static readonly DependencyProperty IsLoadingProperty = 
     DependencyProperty.Register("IsLoading", typeof(bool), typeof(LoadingView), new PropertyMetadata(false, IsActivePropertyChanged)); 

    private static void IsActivePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
    { 
     LoadingView view = d as LoadingView; 
     if (view != null) 
     { 
      // Loading - show ring control 
      if (((bool)e.NewValue) == true) 
      { 
       view.content = view.Content; 
       view.Content = view.m_RingControl; 
       view.m_RingControl.IsActive = true; 
      } 
      else 
      { 
       view.m_RingControl.IsActive = false; 
       view.Content = view.content; 
      } 
     } 
    } 
} 

и я поставил на связывание LoadingView.IsLoading с некоторыми IsLoading (или IsBusy) в ViewModel

ответ

1

Это предмет, который может получить действительно сложный очень быстро.

Я бы посоветовал небольшое изменение в подходе - вместо того, чтобы поместить свойство IsBusy в базовую модель представления, вместо этого сделайте его абстрактным, чтобы каждая производная модель viewmodel должна была выполнить свою собственную конкретную проверку.

public class BaseViewModel : INotifyPropertyChanged 
{ 

    public abstract bool IsBusy { get; } 

} 

public class FancyViewModel : BaseViewModel 
{ 

    public override bool IsBusy 
    { 
     get { return [check #1] && [check #2]...; } 
    } 
} 

Теперь каждый конкретный режим просмотра определяет, занят ли он. Неочищенный механизм состоит в том, чтобы иметь счетчик, который вы увеличиваете каждый раз при срабатывании асинхронной функции и уменьшаете ее, когда операция заканчивается - если ее значение равно нулю, тогда нет текущих асинхронных операций. При использовании флагов или счетчиков следует учитывать различные проблемы с чтением свойств, которые могут возникнуть из-за compiler optimisations, научиться использовать ключевое слово volatile в нужном месте.

В качестве альтернативы вместо хранения счетчика вы можете использовать поточный сейф CountdownEvent class. Если вы хотите получить действительно продвинутый, то вы можете проверить различные механизмы сигнализации нитей в System.Threading namespace или посмотреть на task parallelism и Task object.

+0

Благодарим вас за ответ, но мое намерение было скорее о представлении, чем в viewmodel. – user2853648

+0

@ user2853648 Я знаю, что мой ответ был направлен на то, чтобы помочь вам объединить результаты кучи асинхронных методов в одно свойство IsBusy. Если вы все еще ищете элемент управления, попробуйте [BusyIndicator] (http://elegantcode.com/2011/10/07/extended-wpf-toolkitusing-the-busyindicator/) – slugster

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