2014-09-02 4 views
1

Я довольно новичок в WPF, и сейчас я пытаюсь привыкнуть к шаблону MVVM. Прямо сейчас у меня есть простое приложение, в котором у меня есть коллекция ViewModels, которую я показываю в сетке. Когда я дважды нажимаю на строку в сетке, я хочу показать подробности ViewModel.WPF MVVM и передача viewmodels к виду

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

Итак, что мне делать в этом случае? Должен ли я просто сломать шаблон MVVM или есть ли какие-то приятные и чистые решения для этого, которые соответствуют шаблону MVVM?

ответ

4

Есть много способов прохождения модели представления к представлению, как вы это называете, или установить модель представления в качестве DataContext либо в Window или UserControl, а другие могут называть его. Проще всего именно это:

В конструктор вида:

public partial class SomeView 
{ 
    InitializeComponent(); 
    DataContext = new SomeViewModel(); 
} 

Более MVVM способом можно было бы определить DataTemplate с в App.xaml для каждой модели представления, которая определяет, какой вид каждый будет использовать:

<DataTemplate DataType="{x:Type YourViewModelsPrefix:YourViewModel"> 
    <YourViewsPrefix:YourView /> 
</DataTemplate> 
... 
<DataTemplate DataType="{x:Type YourViewModelsPrefix:AnotherViewModel"> 
    <YourViewsPrefix:AnotherView /> 
</DataTemplate> 

Теперь, когда Framework сталкивается с экземпляром этих классов модели представлений, он отображает связанный с ним вид. Вы можете отобразить их, имея свойство типа вашей модели представления, используя ContentControl так:

<ContentControl Content="{Binding YourViewModelProperty}" /> 

Или даже в коллекции, как это:

<ListBox ItemsSource="{Binding YourViewModelCollectionProperty}" /> 
0

Я согласен с @ ответ Шеридана и хотел бы только добавить еще один способ создания экземпляра представления с моделью зрения: вы можете использовать шаблон Factory, может быть, как это:

public class ViewFactory 
{ 
    public UIElement Create(object context) 
    { 
     // Create the view model 
     // You can pass in various information by parameters 
     // as I do with context (Constructor Injection) 
     var viewModel = new ViewModel(context); 

     // Create the view and set the view model as data context 
     var view = new View { DataContext = viewModel }; 
     return view; 
    } 
} 

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

2

«Должен ли я просто разорвать шаблон MVVM?»

Ну, пожалуйста, подумайте, чтобы узнать больше о шаблоне, узнать, что значит «сломать». Основная цель этого шаблона - сохранить отчетность, чтобы получить проверяемый и поддерживаемый код. Для этого есть много новостей, как показать в этом вопросе: MVVM: Tutorial from start to finish?

В любом случае, более конкретно о вашем вопросе, что вы ищете, как установить DataContext.

«каким-то образом пройти инстанс ViewModel в поле зрения, когда он будет создан»

Да, вы получите его, если вы назначаете DataContext с ViewModel в конструкторе вашей точки зрения, она могла бы работать но это приемлемо только в том случае, если viewModel отвечает за создание представления (что может быть приемлемым в действительно ситуации). Можно даже написать что-то подобное, чтобы сразу установить DataContext вне вашего зрения:

var l_window = new MyView { DataContext = new MyViewModel() }; 
l_window.Show(); 

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

Более распространенное решение заключается в том, чтобы вводить dataContext в контейнер IOC (например, призму). Вы создаете все необходимые ViewModel при запуске программного обеспечения и сохраняете их в контейнере IOC. Затем, когда представление создается, вы запрашиваете этот контейнер, чтобы получить экземпляр вашей модели viewModel.

Пример может быть: экспортировать ViewModel в PRISM:

[Export] 
public class MyViewModel {...} 

, а затем импортировать его на вашем взгляде:

[Import] 
private MyViewModel ViewModel 
{ 
set { this.DataContext = value; } 
get { return this.DataContext as MyViewModel; } 
} 

Надеется, что это помогает.

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