使用ViewModel公开嵌套模型

时间:2012-08-03 03:30:25

标签: c# wpf mvvm

我正在寻找一个我正在整理的WPF / MVVM应用程序的一些指导。谷歌今天没有帮助我。

所以我有一个应用程序,其中包含一些模型(域对象),其他模型作为属性。现在,我只是展开嵌套对象,并在包含对象的ViewModel中公开属性。

随着我的模型越来越复杂,我正在努力解决如何在某种程度上打破ViewModel的问题。我正在走向“复合视图”,其中“包含”对象具有其视图和视图。 ViewModel和“嵌套”对象也有自己的。这也会给我一些可重复使用的代码,这将是一个加号。

作为一个非常简单的例子,假设我有一个建筑物,每个建筑物都有一些属性,还有一个地址,如下所示:

public class Building
{
     public string Name { get; set;}
     public Address Address { get; set;}
}

public class Address
{
    public string Number { get; set; }
    public string Street { get; set; }
}

然后,我有一个用于构建的ViewModel,以及一个用于Address的ViewModel(由BuildingViewModel公开):

public class BuildingViewModel
{
    public string Name { get; set; } // from model
    public AddressViewModel Address { get; set; } // a wrapped instance of Address
    // INPC, etc... 
}

public class AddressViewModel
{
    public string Number { get; set; } // originally from Building 
    public string Street { get; set; }
    // INPC, etc...
}

因此,我没有显示,我有一个BuildingView和一个嵌套的AddressView。我只是首先使用ViewModel和datatemplates。

现在,如何保持Address对象同步?一旦我将它们分成两个ViewModel,我就得到了Address对象的两个实例。在我完成的所有搜索中,我已经看到使用来回传递对象,并且已经提到了“观察者”模式。

我是朝着正确的方向前进,还是我错过了一些非常简单的事情?任何建议都表示赞赏。

FWIW,我已经拼凑了自己的框架,因为我一直对学习曲线持怀疑态度。此外,到目前为止它还相当简单。

2 个答案:

答案 0 :(得分:1)

我认为您当前的方向是暴露太多信息,并阻止模型和视图模型松散耦合。

我只有一个模型实例封装了所有数据(建筑物和地址)。任何viewmodel都会通过静态方法获取这个实例。

然后我会在查询你的数据库的模型中公开查询方法,例如返回一个结果列表,然后你可以填充你的视图。

请注意,列表不必是建筑物或地址列表,每个列表项都包含对您的viewmodel最有用的内容,例如来自builidng的某些字段,以及来自嵌套地址记录的其他字段。

顺便说一句,Wpf有一个很好的机制来直接链接viewmodel数据和视图,例如查询结果与列表框,而viewmodel不需要知道任何有关视图的信息。

答案 1 :(得分:1)

您可以使用类型为address的后端字段将您的地址存储在AddressViewModel中:

    public class AddressViewModel
    {
        private readonly Address _address;

        public AddressViewModel(Address address)
        {
            _address = address;
        }

        public string Number 
        { 
            get { return _address.Number; }
            set { _adress.Number = value; }
        }
        public string Street
        { 
            get { return _address.Street; }
            set { _adress.Street = value; }
        }
    }

我希望你能用我的代码做点什么: - )

修改

接下来尝试:)

我认为解决问题的最佳方法是使用一些工厂类/方法来获取模型。例如,您有一个带有GetAddressList()方法的AddessList类。该方法返回Address模型对象的列表。在第一次调用之后,您将返回的对象缓存在AddressList类中,对于下一次调用,您将返回缓存的列表。

    public static class AddressList
    {
        private static List<Address> _backend;

        private static AddressList()
        {
            _backend = new List<Address>();
        }

        public static List<Address> GetAddressList()
        {
            if(_backend.Count == 0)
            {
                //Here you can load your models from your data source
            }
            else
            {
                return _backend;
            }
        }
    }