我遇到了解决设计问题的最佳方法。我希望得到一些想法/建议。这是一个WPF 4.0桌面应用程序。
我正在使用Entity Framework(v6,模型优先),它为我生成了ObservableCollection
个POCO类,我正在使用它作为我的模型的基础。我将这些暴露给我的ViewModel,我的目的是将集合的{ReadOnly
版本)从这里暴露给我的View,但是我需要在接口运行之前为集合中的每个对象添加一些行为(这是非常“查看”功能 - 记录与集合的每个成员相对应的用户界面状态,而不是应该保留的数据。
在我看来,我有两个选择:
是否有解决此类问题的标准方法?
编辑:使问题参数更具体
我有一个X
的集合,每个集合都包含Y
的集合(因为数据库中存在一个 - >多个关系)。对于上面的选项2,我需要包装所有X
和所有Y
。我可以相对轻松地创建WrappedX
的集合,但我不能轻易地将每个X
的成员集合更改为WrappedY
。我必须在X的包装器中克隆Y
个集合,并保留所有Y
<> WrappedY
个集合同步。如果有更好的方法,这就是让我不自觉地实施选项2的开销。
答案 0 :(得分:0)
我使用通用包装类来完成此操作。我用它来保存像我选择的POCO模型中的IsSelected。注意:我在我的POCO类中实现了INotifyPropertyChanged,以避免必须将所有属性映射到我的DisplayItem,但听起来你不需要它,因为你的只是readonly。
public class DisplayItemBase<T> : ObservableObject
{
private T _Item;
public T Item
{
get { return _Item; }
set
{
if (value == _Item)
return;
_Item = value;
RaisePropertyChanged("Item");
}
}
private bool _IsSelected;
public bool IsSelected
{
get { return _Item; }
set
{
if (value == _Item)
return;
_Item = value;
RaisePropertyChanged("Item");
}
}
//More reusable properties/methods/etc
}
然后,如果我有一个特定的POCO实体需要特定的UI相关功能而不属于我的任何其他POCO,我会为那个继承自DisplayItemBase的那个创建一个特定的类。 / p>
public class MyEntityDisplayItem : DisplayItemBase<MyEntity>
{
private DisplayItemCollectionBase<ChildEntity> _ChildEntities;
public DisplayItemCollectionBase<ChildEntity> ChildEntities
{
get { return _ChildEntities; }
set
{
if (value == _ChildEntities)
return;
_ChildEntities = value;
RaisePropertyChanged("ChildEntities");
}
}
public MyEntityDisplayItem(MyEntity myEntity)
{
ChildEntities = new DisplayItemCollectionBase<ChildEntity>(myEntity.ChildEntities);
Item = myEntity;
}
public void AddChildEntity(ChildEntity childEntity)
{
ChildEntities.Add(childEntity);
Item.ChildEntities.Add(childEntity);
}
}
编辑:回答评论
我还创建了一个DisplayItemCollectionBase,它可以接受我的实体,将其包装起来并将其添加到这样的集合中。
public class DisplayItemCollectionBase<T> : ObservableCollection<DisplayItemBase<T>>
{
public DisplayItemCollectionBase(IEnumerable<T> items)
{
this.AddRange(items)
}
public void AddRange(IEnumerable<T> items)
{
foreach (var item in items)
this.Add(item);
}
public void Add(T item)
{
this.Add(new DisplayItemBase<T>(item));
}
}
这可能有点不对,因为我会从脑子里走出来,但你应该得到要点。
我在ViewModel中使用它(简化):
public void RefreshFromDatabase()
{
var repository = new MyEntityRepository();
IEnumerable<MyEntity> myEntities = repository.GetAll();
MyEntityCollection = new DisplayItemCollectionBase<MyEntity>(myEntities);
}