MVVM выполняет команду на ViewModel из другой ViewModel
Я борюсь около 14 дней с простой задачей: в базе данных у меня есть определения для категорий оборудования. Например :
- жесткий диск
- внутренние
- внешний
- вспышка
этот список находится в базе данных, определенной следующим образом:
[ID - ParrentID - Name] : 1 - 0 - HDD, 2 - 1 - Internal, 3 - 1 - External, 4 - 1 - Flash.
через Entity Framework я получаю эти строки в свое приложение. Из этих плоских данных я затем создаю структурированный объект, который является моим DataModel. Эта модель определяется следующим образом :
public class Category
{
private int _id = -1;
private string _name = "";
private List<Category> _subCategories = null;
// property getters and setters, constructors, and bool HasSubCategories
}
теперь из них я создаю ViewModel под названием SubCategoryViewModel к которому привязан мой TreeView. Таким образом, я могу просматривать свои категории в treeview и с моей определенной и поддерживаемой иерархией. Это работает просто отлично. В SubCategoryViewModel определена в команда через прикрепленное поведение для MouseDoubleClick который также привязан к TreeView. Итак, когда пользователь doubleclicks по пункту, в SubViewCategoryModel определенный метод будет выполнять определенный код. Список SubCategoryViewModel вложен в HWDocumentViewModel который является основным ViewModel для моего окна. То, что мне нужно сейчас, очевидно : когда пользователь doubleclicks на элементе в TreeView, мне нужно загрузить элементы из базы данных и показать их в ListView. Мое мнение таково, что в HWDocumentViewModel мне нужно определить коллекцию элементов и загрузить их согласно выбранной категории в ListView. Но я не знаю, как выполнить метод на HWDocumentViewModel из SubCategoryViewModel. Потому что: TreeView привязан к списку SubCategoryViewModel элементы, поэтому, когда происходит DoubleClick, метод on SubCategoryViewModel выполняется. Я ищу способ, как выполнить метод на main ViewModel (HWDocumentViewModel).
я попробовал этот подход:
Я создал свойство:public static SubCategoryViewModel SelectedCategory
on HWDocumentViewModel
. Когда происходит doubleclick, я устанавливаю это свойство из SubCategoryViewModel как this
. Итак, в этом свойстве находится объект, который выполнил делегат события doubleclick. Отлично, теперь у меня в модели HWDocumentView есть объект, который выбрал пользователь.
Итак, мне нужно загрузить элементы в ListView. Но, я загружу их из метода в SubCategoryViewModel ? Я так не думаю. Вместо этого я должен загрузить их из модели Main View, создав для них ViewModel и свяжите его с ListView, правильно ? Но как я могу из SubCategoryViewModel вызвать метод в HWDocumentViewModel ? Должен ли я написать статический метод
на HWDocumentViewModel, который будет доступен из SubCategoryViewModel ?
или есть способ, как вызвать команду, определенную на HWDocumentViewModel из SubCategoryViewModel ?
или вообще, правильно ли я подошел к созданию складского приложения в WPF ?
спасибо много.
EDIT: XAML для моего TreeView выглядит так:
<TreeView x:Name="tvCategories" Background="White" ItemsSource="{Binding Categories}">
<TreeView.ItemContainerStyle>
<Style TargetType="{x:Type TreeViewItem}">
<Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}" />
<Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" />
<Setter Property="FontWeight" Value="Normal" />
<Setter Property="behaviors:MouseDoubleClick.Command" Value="{Binding MouseDoubleClickCommand}" />
<Setter Property="behaviors:MouseDoubleClick.CommandParameter" Value="{Binding}" />
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="FontWeight" Value="Bold" />
</Trigger>
</Style.Triggers>
</Style>
</TreeView.ItemContainerStyle>
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type localvm:SubCategoryViewModel}" ItemsSource="{Binding Children}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding CategoryName}" />
</StackPanel>
</HierarchicalDataTemplate>
</TreeView.Resources>
</TreeView>
2 ответов
Я не уверен, что вижу проблему. У вас есть дерево подкатегорий, и когда один выбран, соответствующий SubCategoryViewModel
устанавливает себя как SelectedCategory
на главную HWDocumentViewModel
. Это кажется разумным подходом.
так зачем вам нужно вызывать команду? Почему вы не можете просто загрузить новый список в HWDocumentViewModel
в ответ на изменение своего SelectedCategory
свойство (т. е. в сеттере)?
если вы действительно должны использовать команду для вызова нагрузки, просто сохраните ссылку на свой основной HWDocumentViewModel
в каждом элементе SubCategoryViewModel
, и вызовите команду с простым:
_mainViewModel.LoadCategoryCommand.Execute();
с MVVM и пытается общаться между View и ViewModel или между ViewModels настройка издателя / подписчика работает хорошо или парадигма обмена сообщениями, как то, что находится в MVVMLight или Prism. Я опубликовал ответ на настройку обмена сообщениями MVVM Light здесь
в сообщении вы можете передать объект, который содержит любые данные, которые вы хотели бы отправить туда и обратно между моделями представления.
Я настоятельно рекомендую использовать фреймворк при работе с mvvm, который он делает вроде намного проще. MVVM Framework сравнение ссылка на ответ, который идет через сравнение некоторых основных структур.