2013-06-05 2 views
2

Я хотел бы узнать наиболее подходящий способ сделать это: у меня есть Listview в моем GameView, который связан с ObservableCollection<Adventurer>. При двойном щелчке по ячейке мне нужно новое окно (или что-то еще, если что-то более подходящее), чтобы открыть и отобразить данные о правильном Adventurer в соответствии с ячейкой. Пока что я не смог. Это то, что у меня есть до сих пор (это мало, но я ничего не пробовал).WPF & MVVM Light-Pass объект в новом окне

Спусковой/команда в моей ListView в GameView.xaml

<i:Interaction.Triggers> 
    <i:EventTrigger EventName="MouseDoubleClick"> 
     <cmd:EventToCommand Command="{Binding Mode=OneWay, Path=ShowAdvCommand}" 
          CommandParameter="{Binding ElementName=AdvListView, 
                 Path=SelectedItem}" 
          PassEventArgsToCommand="True" /> 
    </i:EventTrigger> 
</i:Interaction.Triggers> 

И команда в GameViewModel.cs

ShowAdvCommand = new RelayCommand<Adventurer>(p => 
{ 
    System.Windows.MessageBox.Show(p.Name); 
}); 

MessageBox только там, чтобы подтвердить, что Eventtocommand работал.

Мне по существу нужен контейнер, который примет правильный Adventurer в качестве параметра после двойного щелчка по ячейке списка и позволит мне отображать данные, относящиеся к этому экземпляру. Я также предпочел бы придерживаться чего-то MVVM-friendly.

Любые советы были бы весьма полезными.

Update: я, возможно, сделал немного прогресса:

GameViewModel:

ShowAdvCommand = new RelayCommand<Adventurer>(p => 
{ 
    AdventurerView adv = new AdventurerView(p); 
    adv.Show(); 
}); 

AdventurerView:

public partial class AdventurerView : Window 
{ 
    Adventurer adv; 

    public AdventurerView(Adventurer adv) 
    { 
     this.adv = adv; 
     InitializeComponent(); 
    } 
} 

Теперь мне нужно, чтобы выяснить, как сделать эту работу в XAML, привязка данных и тому подобное.

Обновление: ... и затем я понял, что это полностью противоречит MVVM. Есть ли у кого-нибудь совет?

Обновление: Помощник MVVM Light поможет мне здесь? Я занимался этим, но не получил работу.

Обновление: Этот вопрос по-прежнему в воздухе. Я пробовал подход Prism, но был некоторый конфликт между Prism и MVVM Light, который вызвал больше проблем, чем того стоило. Я открыт для любых идей, совместимых с MVVM Light и шаблоном MVVM в целом.

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

ответ

4

В подобной ситуации я использовал Messenger MvvmLight, и он работал очень хорошо. При двойном щелчке отправьте сообщение из своей модели просмотра, содержащей объект, который вы хотите передать. Где-то вам нужно будет зарегистрироваться для получения сообщения, в зависимости от того, как вы настроили свои виды и режимы просмотра, которые нужно активировать.

Вы можете зарегистрироваться для получения сообщения в своем MainPage.xaml и либо передать объект прямо в конструктор представления, либо получить доступ к DataContext представления через интерфейс для передачи объекта, в зависимости от того, используете ли вы модель viewmodel в тебе, детство. Например.

AdventurerView adv = new AdventurerView(); 
IEntityViewModel vm = adv.DataContext as IEntityViewModel; 
vm.SetCurrentEntity(entity); 
adv.Show(); 

IEntityViewModel может выглядеть следующим образом:

public interface IEntityViewModel<T> where T : class 
{ 
    void SetCurrentEntity(T entity); 
} 

модели представления будет реализовывать этот интерфейс:

public class AdventurerViewModel : IEntityViewModel<Adventurer> 
{ 
    public void SetCurrentEntity(Adventurer entity) 
    { 
     // Do what you need to with the entity - depending on your needs, 
     // you might keep it intact in case editing is cancelled, and just 
     // work on a copy. 
    } 
} 
+0

Что такое 'IEntityViewModel'? Я искал вокруг, но не нашел никакой информации об этом. –

+0

Это не часть каких-либо фреймворков, просто интерфейс, который я использую, чтобы немного отделить представление от viewmodel. Редактирование моего вопроса для включения примера ... – Alyce

0

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

Один из шаблонов, который появился, представляет собой концепцию, известную как «проводник экрана». Это верхний уровень ViewModel или контроллер, который обрабатывает, какой ViewModel представляет основное окно. Опять же, много разных способов сделать это. Например, ViewModel может поднять стандартное событие .net, которое обрабатывает Screen Conductor. Вы можете использовать систему передачи сообщений, такую ​​как EventAggregator Caliburn.Micro или Messenger MVVM Light. Я думаю, что MEFedMVVM также имеет агрегатор событий для этого.

Caliburn.Micro также имеет WindowManager, который вы можете передать в ViewModel и автоматически найти соответствующий просмотр и управлять временем жизни окна.

Много вариантов. Найдите тот, который работает лучше всего для вас.

+1

* [...] правильный MVVM не создавал бы представление и не пропускал бы модель представления через конструктор. * - Хм, почему бы это не было правильно? Единственное ограничение между 'View' и' ViewModel', которое я знаю, это то, что 'View' может знать' ViewModel', но 'ViewModel' не должен знать о' View'. – DHN

+0

надлежащий mvvm отделяет представление от viewmodel таким образом, что между ними нет прямой зависимости. – bryanbcook

+0

Как можно что-то отделить от объекта, если оно ссылается на его свойства (привязка)? - O.o – DHN

0

Это приятный случай для взаимодействия с Prism's InteractionRequest. По сути, у вас есть объект InteractionRequest на вашем ViewModel, который вы поднимаете при двойном щелчке (внутри вашей команды двойного щелчка). В вашем представлении есть действие, которое обрабатывает событие Raised и показывает новое представление. Вы передаете новый ViewModel для этого взаимодействия, и это DataContext для окна, которое будет отображаться. Here's some good information, чтобы вы начали. Вот как я показываю все дочерние окна в своем приложении.

+0

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

+0

@ DennisE да, мне потребовалось немного, чтобы все наладилось. Приятно, что вам не нужно полноценное приложение Prism; вы можете просто использовать объекты InteractionRequest. Удачи, дайте мне знать, если у вас есть вопросы. – Thelonias

+0

Код в опубликованной вами ссылке был полон ошибок и не компилировался, но я нашел этот образец, который, кажется, делает все, что мне нужно: http://www.codeproject.com/Articles/269364/MVVM-PRISM -Modal-Windows-by-use-Interaction-Requ - этот образец включает в себя множество классов, и мне было интересно, что мне нужно от них, чтобы достичь того, что я пытаюсь сделать (чтобы отображать информацию об объекте и, возможно, отправлять обновленные данные назад). Если вы не возражаете помочь мне разобраться с этим, возможно, мы могли бы начать чат? –

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