我已经苦恼了14天,因为有一个简单的任务:在数据库中,我定义了硬件类别。例如:
- HDD
- 内置
- 外置
- 闪存
这个列表在数据库中是这样定义的:
[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
}
现在,我创建了一个名为SubCategoryViewModel的ViewModel,并将其绑定到我的TreeView。因此,我可以在TreeView中查看我的类别,并使用我定义和维护的层次结构。这很好用。在SubCategoryViewModel中定义了一个Attached Behavior for MouseDoubleClick的Command,也将其绑定到了TreeView。因此,当用户双击项目时,在SubViewCategoryModel中定义的方法将执行特定代码。 SubCategoryViewModel的列表嵌套在HWDocumentViewModel中,后者是窗口的主要ViewModel。
现在我需要的很明显:当用户在TreeView中双击项目时,我需要从数据库中加载项目并在ListView中显示它们。我认为,在HWDocumentViewModel中,我需要定义一个项目集合,并根据所选类别相应地加载它们到ListView中。但是,我不知道如何从SubCategoryViewModel执行HWDocumentViewModel上的方法。因为:TreeView绑定到SubCategoryViewModel项列表,因此发生DoubleClick时,会执行SubCategoryViewModel上的方法。我正在寻找一种方法,如何在主ViewModel(HWDocumentViewModel)上执行方法。
我尝试了这种方法:
我创建了一个属性:
public static SubCategoryViewModel SelectedCategory
在HWDocumentViewModel
上。当发生双击时,我将此属性从SubCategoryViewModel设置为this
。因此,在此属性中有一个对象,该对象执行了DoubleClick事件委托。太好了,现在我在HWDocumentView模型中拥有用户选择的对象。因此,我需要将项目加载到ListView中。但是,我会从SubCategoryViewModel的方法中加载它们吗?我不这么认为。相反,我应该通过为它们创建一个ViewModel并将其绑定到ListView来从Main View Model中加载它们,对吧?但是,我如何从SubCategoryViewModel中调用HWDocumentViewModel中的方法?我应该写一个静态方法在HWDocumentViewModel上,以便从SubCategoryViewModel中访问它吗?
还是有一种方法可以从SubCategoryViewModel调用在HWDocumentViewModel上定义的Command吗? 或者总的来说,我是否采取了正确的方法来创建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>