C# wpfmvvm绑定。相同的视图,不同的对象

C# wpfmvvm绑定。相同的视图,不同的对象,c#,wpf,linq,mvvm,C#,Wpf,Linq,Mvvm,我正在构建我的第一个WPF应用程序,并努力遵循MVVM原则 我有一种情况,我使用viewModel从我的实体构建一个对象,该实体使用LINQ分布在8个不同的数据库表中,准备填充树视图 这很好用 我现在需要做的是更改绑定到同一视图的对象。例如,在简单的情况下,对象的顺序可能不同,或者更重要的是,我可能会过滤实体的源,这将需要在其他表之间连接一个完全不同的查询,但最终生成的对象将是绑定到我的treeview的相同结构 以下是我的主要方法: public EntityViewModel() {

我正在构建我的第一个WPF应用程序,并努力遵循MVVM原则

我有一种情况,我使用viewModel从我的实体构建一个对象,该实体使用LINQ分布在8个不同的数据库表中,准备填充树视图

这很好用

我现在需要做的是更改绑定到同一视图的对象。例如,在简单的情况下,对象的顺序可能不同,或者更重要的是,我可能会过滤实体的源,这将需要在其他表之间连接一个完全不同的查询,但最终生成的对象将是绑定到我的treeview的相同结构

以下是我的主要方法:

public EntityViewModel()
    {
        using (var model = _app.OrmContext.CreateUnitOfWork())
        {
             // get unique entity names, we always need this in the filtering drop-down
            var names = (
                from tt 
                in model.EntityTypes
                    .OrderBy(o => o.Name)
                    select new EntityType
                    {
                        Name = tt.Name
                    }).Distinct().ToList();

            _entityNamesUnique.AddRange(names);

            var collection =
                from n 
                in names    
                select new EntityCollection
                {
                    entityName = n.Name,
                    tags = (
                        from t in model.Entities
                        join to in model.EntityOutlines on t.Outline equals to
                        where t.EntityType.Name.Equals(n.Name)
                        orderby to.EntityData
                        select new EntityMeta
                        {
                            entityData = to.CData,
                            objectId = to.ObjectId,
                            completed = t.Completed,
                            modified = (DateTime) to.Modified, // no idea why I need to cast this
                            comment = t.EntityType.Comment
                        }
                    ).Distinct().ToList(),
                };

            _entityCollection.AddRange(collection);

        }
    }
我的问题是如何使用MVVM实现这一点?我见过主视图模型和子视图模型的示例,其中页面可能被交换,或者视图中的控件被动态更改。在我的例子中,视图并没有改变——相同的页面,相同的控件——但我正在显著地改变我将要显示的数据

我目前的想法是,我在视图模型类中有一个单独的私有查询方法,用于发送回的每个数据变体,并且我在主视图模型方法中切换,以决定返回哪些数据

我很确定这会奏效,但这是MVVM的方式吗

编辑:为清晰起见

最终的对象将是相同的。结构中实体的分组,如代码中所示。但是,核心实体与当前未包含在该视图中的其他业务对象有关系(此查询仅显示所有内容),因此我需要切换我运行的查询,例如,显示按关系A、B或C分组的此实体结构。在每种情况下,LINQ查询都将非常不同,进一步链接(数据库)实体关系层次结构

因此,考虑到产生的linq查询在每种情况下都会大不相同,那么在MVVM中为每个查询使用一个单独的方法,然后在我的视图模型方法中切换这个方法是否是一种合法的做法

进一步编辑:带代码

我还不完全熟悉MVVM的说法,所以这段伪代码可能有助于说明我的想法。这似乎合理吗

class EntityViewModel {

    public EntityViewModel()
    {
        switch (someEvent)
        {
            case 1:
                buildAllEntityCollection();
            break;

            case 2:
                buildEntitiesGroupedByADifferentObjectA();
            break;

            case 3:
                buildEntitiesGroupedByDifferentObjectsBAndC();
            break;
        }
    }

    private void buildAllEntityCollection()
    {
        // the LINQ query already posted, adds the results of a 
                    //linq query to a list of EntityCollections
        // that is bound to the view
        var collection = some.Linq.query.Tolist();
         _entityCollection.AddRange(collection);
    }

    private void buildEntitiesGroupedByADifferentObjectA()
    {
        // a completely different LINQ query populating 
                    // the same list, binding to the same view
        var collection = some.Linq.query.Tolist();
         _entityCollection.AddRange(collection);
    }

    private void buildEntitiesGroupedByDifferentObjectsBAndC()
    {
        // a completely different LINQ query populating 
                    // the same list, binding to the same view
        var collection = some.Linq.query.Tolist();
         _entityCollection.AddRange(collection);
    }

    List<EntityCollection> EntityCollection
    {
         get { return _entityCollection; }
    }
}    
class EntityViewModel{
公共实体视图模型()
{
开关(someEvent)
{
案例1:
buildalEntityCollection();
打破
案例2:
BuildEntitiesGroupedByAfferenceTobjecta();
打破
案例3:
BuildEntities按不同的对象B和C()分组;
打破
}
}
私有void buildalEntityCollection()
{
//已发布的LINQ查询将添加
//linq查询到EntityCollections列表
//这是必然的看法
var collection=some.Linq.query.Tolist();
_entityCollection.AddRange(集合);
}
私有void BuildEntityGroupedByAfferenceTobjecta()
{
//完全不同的LINQ查询填充
//相同的列表,绑定到相同的视图
var collection=some.Linq.query.Tolist();
_entityCollection.AddRange(集合);
}
私有void buildEntities按不同的对象B和C()分组
{
//完全不同的LINQ查询填充
//相同的列表,绑定到相同的视图
var collection=some.Linq.query.Tolist();
_entityCollection.AddRange(集合);
}
列表实体集合
{
获取{return\u entityCollection;}
}
}    

根据您的解释,就我所能理解的数据结构而言,您可以:

  • 设计视图(符合最终用户的要求)
  • 设计可容纳视图的ViewModel
  • 为存储库/数据访问类上的每个linq查询提供一个方法,用于查询正确的数据结构并返回ViewModel的实例
MVVM中的ViewModel负责缩小视图和ViewModel之间的差距。如果生成的视图和视图模型相同,则几乎没有理由制作多个版本(除非新的洞察提示您这样做)

桥接是通过调用模型上的方法/访问属性以及提供视图可以使用的属性和命令来完成的。这样,ViewModel只知道模型,并允许视图访问数据和操作


ViewModel不知道视图意味着ViewModel对视图没有依赖关系。反过来,视图将依赖于ViewModel,因为它将指向ViewModel的属性和命令。

对象类型之间有什么不同?属性名称、属性类型、层次结构?您可能会编写一个非常灵活的视图(类似于网格控件),这可能会比创建多个视图花费更多的时间。我更新了这个问题以提供一些说明。嗨,我添加了一些伪代码来说明我的观点,这是正确的方法吗?我想我的困惑在于把视图模型代码放在哪里。显然,ThisEntity.GetEntityByName()存在于该实体的模型类中,但我想知道在哪里放置将大量实体合并到自定义对象中的方法。我认为这就是视图模型的用途?正确,将模型转换为ViewModel的逻辑应该在ViewModel中,或者在Moel和ViewModel之间。模型不应了解ViewModel。通常,我会添加一层存储库,其中包含(Linq)查询。@erNodeWeard请解释一下:“MVVM中的ViewModel负责弥合视图和ViewModel之间的差距。”。。。ViewModel怎么可能同时位于间隙的一侧。。。同时又是它自己和风景之间的桥梁?第二个问题,更严重:在t