c# - MVVM 从其他 ViewModel 在 ViewModel 上执行命令

标签 c# wpf mvvm icommand

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

  1. 硬盘
    • 内部
    • 外部
    • 快闪

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

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

通过 Entity Framework,我将这些行添加到我的应用程序中。然后我从这个平面数据创建结构化对象,这是我的数据模型。该模型定义如下:

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

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

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

非常感谢。

编辑:我的 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();

关于c# - MVVM 从其他 ViewModel 在 ViewModel 上执行命令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10061090/

相关文章:

iOS MVVM 处理初始 View 状态

silverlight - 一个 View 模型用于多个页面

c# - 从字符串中删除空格

c# - 如何使用 LINQ 在 ASP.NET Core 中从 ModelState 中获取充满错误消息的 IEnumerable

c# - 创建文本框问题?

wpf - 将列表绑定(bind)到 WPF 中的列表框

c# - WPF如何处理异常并继续

c# - 将 JSON 字符串粘贴到 Visual Studio 中

c# - 使用 LINQ 从列表中选择项目,其中子项包含另一个列表中的项目

c# - 如何使用 Bing map 检索邮政地址的纬度和经度?