我们有一个Entity框架模型,它包含名为QuoteStatus和SystemStatus的类,它们分别为引用和系统的状态建模。这些类中的每一个都有一个导航属性,该属性是一个集合,其中包含在状态更改时要通知的人员的电子邮件。 QuoteStatus类看起来像这样(简化)......
public class QuoteStatus {
public int ID { get; set; }
public string Name { get; set; }
public List<QuoteStatusNotification> QuoteStatusNotifications;
}
public class QuoteStatusNotification {
public int ID { get; set; }
public string Email { get; set; }
}
SystemStatus和SystemStatusNotification类非常相似。
现在,我们希望有一个WPF窗口,可用于维护这两种类型的状态(以及将来出现的任何状态)。我们的想法是在窗口顶部有一个下拉控件,用户可以在其中指定要显示的状态类型(引用或系统),并将值发送到视图模型。
视图模型将具有数据的私有变量...
private List<QuoteStatus> _quoteStatuses;
private List<SystemStatus> _systemStatuses;
我们希望视图模型具有公共Statuses属性,该属性可以绑定到视图上的网格。根据用户在下拉列表中选择的值,Statuses属性将包含_quoteStatuses集合或_systemStatuses集合。
我们通过创建一个基本Status类,并使QuoteStatus和SystemStatus类继承它来实现。那很好。
我们遇到了子集合的问题。我们希望Status基类具有StatusNotifications集合,该集合将是QuoteStatusNotification类或SystemStatusNotification类的集合。我们无法弄清楚如何创建StatusNotifications集合。
从another thread here(参见接受的答案中的第二个建议),看起来我可以用协方差来做到这一点,但我无法理解如何做到这一点。
任何人都可以解释一下吗?
答案 0 :(得分:2)
简单继承:
public class StatusBaseClass
{
public List<StatusNotification> StatusNotifications;
}
public class QuoteStatus : StatusBaseClass
{
}
public class SystemStatus : StatusBaseClass
{
}
public class StatusNotification
{
}
public class QuoteStatusNotification : StatusNotification
{
}
public class SystemtatusNotification : StatusNotification
{
}
您可以将QuoteStatusNotificatio或SystemStatusNotification添加到基类列表
你可以做的就是你的xaml非常整洁,例如为列表视图中的两个类提供不同的UI。见这里:DataTemplate for each DataType in a GridViewColumn CellTemplate
例如:
<ListView ItemsSource="{Binding Statuses}">
<ListView.Resources>
<DataTemplate DataType="{x:Type viewModel:SystemStatus}">
</DataTemplate>
<DataTemplate DataType="{x:Type viewModel:QuoteStatus}">
</DataTemplate>
</ListView.Resources>
</ListView>
您正在尝试做的更多细节,并且可能能够提供更多帮助。
答案 1 :(得分:0)
创建一个基类,该基类具有两种类型共有的属性。然后你可以通过
List<StatusBaseClass> statuses;
您可以将任何一种类型放入此列表中。
如果是混合列表,那么您可以通过以下方式获取各个类型:
var quoteStatuses = statuses.OfType<QuoteStatus>();
var systemStatuses = statuses.OfType<SystemStatus>();