MVVM выполняет команду на ViewModel из другой ViewModel

Я борюсь около 14 дней с простой задачей: в базе данных у меня есть определения для категорий оборудования. Например :

  1. жесткий диск
    • внутренние
    • внешний
    • вспышка

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

    [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 сравнение ссылка на ответ, который идет через сравнение некоторых основных структур.