2012-02-16 2 views
1

Я использую шаблон MVVM в своем многопоточном WPF-приложении.Привязка к свойству объекта, созданного потоком, работающим на фоне

Теперь в модели я (я пропустил очевидную реализацию интерфейса INotifyPropertyChanged, чтобы сделать его более ясным):

public class ShallowModel : INotifyPropertyChanged 
{ 
    private string _dbState; 
    public string DbState 
    { 
    get { return _dbState; } 
    set 
    { 
     _dbState = value; 
     OnPropertyChanged("DbState") // ofc there is implementation of this 
    } 
    } 
    private InsideObject _inObject; 
    public InsideObject InObject 
    { 
    get { return _inObject; } 
    set 
    { 
     _inObject = value; 
     OnPropertyChanged("InObject") 
    } 
    } 
} 

public class InsideModel : INotifyPropertyChanged 
{ 
    private string _actState; 
    public string ActState 
    { 
    get { return _actState; } 
    set 
    { 
     _actState= value; 
     OnPropertyChanged("ActState") 
    } 
    } 
} 

сказать, что я TextBlocks на Вид:

<TextBlock Text={Binding ActObjectState}/> 
<TextBlock Text={Binding DbState}/> 

Теперь есть часть проблематичной ViewModel:

public class ViewModel : INotifyPropertyChanged 
{ 
    private ShallowModel _model; 
    public string ActObjectState 
    { 
    get 
    { 
     if(_model.InObject != null) 
     return _model.InObject.ActState; 
     else 
     return null; 
    } 
    } 
    public string DbState 
    { 
    get 
    { 
     return _model.DbState; 
    } 
    } 
} 

Проблема в том, что ActObjectSta te и DbState не обновляются, когда фоновый поток обновляет свойства ShallowModel и/или InsideModel. Мои вопросы:

  1. Должен ли я добавить модель общественной собственности на ViewModel и связывания зрения как {Binding Path = Model.DbState}? Я думаю, что это нарушает идею MVVM - View не должен знать о модели.

  2. InObject in ShallowModel создан новым путем после нажатия кнопки Пользовательский интерфейс. Поэтому при создании ViewModel InObject имеет значение NULL. Как-то - после того, как он создан потоком - ActObjectState не обновляется. Как заставить его работать? Сделать привязку, например {Binding Path = Model.InObject.ActState}? Это подразумевает необходимость получения знаний о модели дизайнером пользовательского интерфейса.

Thx, СРЮ для моего английского

+0

Это должно, безусловно, поможет вам [наследовать INotifyPropertyChanged] [1] [1]: http://stackoverflow.com/ вопросы/6871952/silverlight-checkbox-results –

+0

Я не уверен, что вы на самом деле имеете в виду. Внедрен весь интерфейс INotifyPropertyChanged. Если он также используется в ViewModel, даже если эти свойства не заданы ViewModel, а Model - оба из них заданы в результате действия фонового потока. – Joe

+0

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

ответ

0

Я бы принял ваше предложение 1. его самый простой способ, и я не вижу нарушения шаблона MVVM.

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

при работе с потоками быть в курсе диспетчерских вещей, но я думаю, что вы знаете, что

+0

Я использую диспетчер, вызывая и т. Д., Когда это необходимо. Спасибо. Мне нужно, чтобы пользовательский интерфейс обновлялся по модели. Поэтому я мог бы поместить некоторую модельную логику в viewmodel, и я уверен, что это сработает. Мое 1. предложение кажется грязным для меня. – Joe

+0

В конце концов я принял мое предложение №1 из-за отсутствия идей (или время для реализации, как писал Антон Тихий). Спасибо всем вам. – Joe

0

Если поток создан ShallowModel вам нужно поднять все свойства, которые связаны с, что на ViewModel. Вы можете поднять String.Empty, чтобы сообщить механизму привязки данных, чтобы получить все связанные свойства. Но поскольку вы находитесь в потоке, вы не можете просто запустить PropertyChangedEvent, вам нужно отправить его, поэтому поток пользовательского интерфейса может справиться с этим. То, что мы сделали, должно было сделать наш метод повышения уровня ui безопасным с помощью dispatcher.

+0

Фактически ShallowObject передается в ViewModel. Объект InsideObject создается потоком. Ошибок, исключений нет. Это просто не обновление. В ожидании некоторых ответов - я создал простое приложение, где все процессы выполняются потоком пользовательского интерфейса. Он не работал. || Подняв, вы имеете в виду свойство set в ViewModel на 'String.Empty'? – Joe

+0

@Joe Просто маленькая вещь ... это Typo? AstState ! = ActState. – dowhilefor

+0

Да, извините за это. Исправленный. – Joe