многопоточные модели представления - PullRequest
1 голос
/ 13 октября 2010

У меня есть NavigationWindow, которое реализует функциональность мастера, и набор объектов Page, представляющих шаги.

каждая страница использует отдельную модель представления.

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

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

Все это работает нормально, если я не хочу возвращаться обратно в мастере.но если я это сделаю, страница, так как она была выгружена раньше, больше не имеет DataContext и ничего не показывает.

так, чтобы исправить это, мне не нужно избавляться от DataContext на Unloaded, а вместо этогодать указание модели представления запускать / останавливать свои потоки при загрузке / выгрузке собственного окна.Я думаю, для этого мне нужно ввести несколько методов (скажем, Start () и Stop ()) в модели представления, которая будет делать это.и вызывать эти методы из обработчиков страниц Initialized и Unloaded.

, но это ужасно.это слишком сложно, страницы должны знать, чтобы запускать / останавливать потоки, иначе это не будет работать.поэтому я ищу правильный MVVM способ сделать это.

, пожалуйста, помогите Константин

1 Ответ

1 голос
/ 13 октября 2010

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

Первый шаг - изменить структуру взаимодействия: Start() и Stop() являются императивными концепциями, которые, я согласен, кажутся тяжелыми. Вместо этого давайте подумаем о том, что мы делаем как конечный автомат. Я предполагаю, что ваши потоки слушают, поэтому наши состояния могут быть Listening, Idle и Complete. Они соответственно будут соответствовать запущенным потокам, приостановленным потокам и потокам, готовым к завершению.

Надежным способом представления состояний является перечисление:

public enum ListenerState
{
    Idle,

    Listening,

    Complete
}

Вы бы объявили свойство этого типа в вашей модели представления:

public class ListenerModel : ViewModel
{
    private ListenerState _state;

    public ListenerState State
    {
        get { return _state; }
        set
        {
            _state = value;

            RaisePropertyChanged("State");
        }
    }
}

Затем вы будете прослушивать изменения в состоянии и обновлять поток в соответствии:

protected override void OnPropertyChanged(PropertyChangedEventArgs e)
{
    if(e.PropertyName == "State")
    {
        // Manipulate thread for current state
    }
}

Теперь представление просто должно уведомить модель представления о событиях жизненного цикла (что-то, что модель представления не могла знать иначе, кроме как из представления):

private void OnLoaded(object sender, RoutedEventArgs e)
{
    ((ListenerModel) this.DataContext).State = ListenerState.Listening;
}

Если вы хотите полностью отделить представление от модели представления, вы можете создать свойство зависимости в вашем элементе управления для состояния:

public static readonly DependencyProperty ListenerStateProperty =
    DependencyProperty.Register("ListenerState", typeof(ListenerState), typeof(YourControl), null);

public ListenerState ListenerState
{
    get { return (ListenerState) GetValue(ListenerStateProperty); }
    set { SetValue(ListenerStateProperty, value); }
}

Затем установите это свойство в обработчике Loaded вместо ссылки на модель представления:

private void OnLoaded(object sender, RoutedEventArgs e)
{
    this.ListenerState = ListenerState.Listening;
}

Наконец, вы должны привязать свойство к свойству модели представления в разметке:

<local:YourControl ListenerState="{Binding State, Mode=TwoWay}" />
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...