繁体   English   中英

MVVM 从其他 ViewModel 在 ViewModel 上执行命令

[英]MVVM Execute Command on ViewModel from other ViewModel

我现在为一项简单的任务苦苦挣扎了大约 14 天:在数据库中,我有硬件类别的定义。 例如:

  1. 硬盘
    • 内部的
    • 外部的
    • Flash

此列表在数据库中定义如下:

    [ID - ParrentID - Name] : 1 - 0 - HDD, 2 - 1 - Internal, 3 - 1 - External, 4 - 1 - Flash.        

通过实体框架,我将这些行放入我的应用程序中。 然后我根据这个平面数据创建结构化的 object,这是我的数据模型。 这个model定义如下:

public class Category
{
   private int _id = -1;
   private string _name = "";
   private List<Category> _subCategories = null;
// property getters and setters, constructors, and bool HasSubCategories
}  

现在,我从这些创建了名为SubCategoryViewModel的 ViewModel,它绑定了我的 TreeView。因此,我可以在 treeview 中查看我的类别以及我定义和维护的层次结构。 这很好用。 SubCategoryViewModel中通过MouseDoubleClick 的附加行为定义了一个命令,它也绑定到 TreeView。因此,当用户双击 Item 时,在SubViewCategoryModel中定义的方法将执行特定的代码。 SubCategoryViewModel 列表嵌套在 HWDocumentViewModel,它是我的 window 的主要 ViewModel。我现在需要的很明显:当用户双击 TreeView 中的项目时,我需要从数据库加载项目并将它们显示在 ListView 中。 我的意见是,在HWDocumentViewModel中,我需要定义一个项目集合,并将它们相应地加载到 ListView 中的选定类别。 但是,我不知道如何从SubCategoryViewModel对 HWDocumentViewModel 执行方法。 因为:TreeView绑定了SubCategoryViewModel项列表,所以当DoubleClick发生时, SubCategoryViewModel上的方法被执行。 我正在寻找一种方法,如何在主 ViewModel (HWDocumentViewModel) 上执行一个方法。

我试过这种方法:
我在 HWDocumentViewModel 上创建了一个属性: public static SubCategoryViewModel SelectedCategory HWDocumentViewModel 当双击发生时,我将 SubCategoryViewModel 中的这个属性设置为this 因此,在这个属性中是 object,它执行了 doubleclick 事件委托。 太好了,现在我在 HWDocumentView model 和 object 中有了用户选择的。
所以,我需要将项目加载到 ListView。 但是,我会从SubCategoryViewModel中的方法加载它们吗? 我不这么认为。 相反,我应该通过为它们创建一个 ViewModel 并将其绑定到 ListView,从主视图 Model 加载它们,对吗? 但是,如何从 SubCategoryViewModel 调用 HWDocumentViewModel 中的方法? 我应该在可以从 SubCategoryViewModel 访问的 HWDocumentViewModel 上编写 static 方法吗?
或者有没有办法,如何从 SubCategoryViewModel 调用 HWDocumentViewModel 上定义的命令?

或者一般来说,我是否采取了正确的方法在 WPF 中创建类似仓库的应用程序?

非常感谢。

编辑:我的 TreeView 的 XAML 看起来像这样:

<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>

我不确定我是否看到了问题。 You have a tree of subcategories and when one is selected, the appropriate SubCategoryViewModel sets itself as SelectedCategory on the main HWDocumentViewModel . 这似乎是一种合理的做法。

那么为什么需要调用命令呢? 为什么不能在HWDocumentViewModel中加载新列表以响应其SelectedCategory属性的更改(即在 setter 中)?

如果您真的必须使用命令来调用负载,那么只需在每个SubCategoryViewModel中保留对主HWDocumentViewModel的引用,并使用简单的命令调用该命令:

_mainViewModel.LoadCategoryCommand.Execute();

使用 MVVM 并尝试在 View 和 ViewModel 之间或 ViewModel 之间进行通信,发布者/订阅者设置运行良好,或者消息传递范例类似于 MVVMLight 或 Prism 中的范例。 我在这里发布了一个关于 MVVM Light 消息设置的答案

在消息中,您可以发送一个 object,其中包含您希望在视图模型之间来回发送的任何数据。

我强烈建议在使用 mvvm 时使用框架,这样会更容易。 MVVM Framework Comparison是指向通过一些主要框架的比较的答案的链接。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM