简体   繁体   English

我如何提供通用子财产

[英]How do I provide a generic child property

We have an Entity framework model, which contains classes named QuoteStatus and SystemStatus, which model the status of a quote and a system respectively. 我们有一个Entity框架模型,其中包含名为QuoteStatus和SystemStatus的类,它们分别对报价和系统的状态进行建模。 Each of these classes has a navigation property, which is a collection that contains the emails of people who are to be notified when the status changes. 这些类中的每一个都有一个导航属性,该属性是一个集合,其中包含状态更改时将通知的人员的电子邮件。 The QuoteStatus class looks like this (simplified)... 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; }
}

The SystemStatus and SystemStatusNotification classes are remarkably similar. SystemStatus和SystemStatusNotification类非常相似。

Now, we want to have a WPF window that can be used to maintain both types of statuses (and any more that come along in the future). 现在,我们希望有一个WPF窗口,该窗口可用于维护两种类型的状态(以及将来出现的任何状态)。 The idea is to have a dropdown control at the top of the window, where the user specifies the type of status to be shown (quote or system), and the value is sent to the view model. 想法是在窗口顶部具有一个下拉控件,用户可以在其中指定要显示的状态类型(引用或系统),然后将值发送到视图模型。

The view model would have private variables for the data... 视图模型将具有数据的私有变量。

private List<QuoteStatus> _quoteStatuses;
private List<SystemStatus> _systemStatuses;

We want the view model to have a public Statuses property, which can be bound to a grid on the view. 我们希望视图模型具有公共Statuses属性,该属性可以绑定到视图上的网格。 Depending on what value the user chooses in the dropdown, the Statuses property would contain either the _quoteStatuses collection, or the _systemStatuses collection. 根据用户在下拉菜单中选择的值,Status属性将包含_quoteStatuses集合或_systemStatuses集合。

We did that by creating a base Status class, and having the QuoteStatus and SystemStatus classes inherit from it. 我们通过创建基础Status类并让QuoteStatus和SystemStatus类继承来做到这一点。 That was fine. 很好

We ran into a problem with the child collections. 我们遇到了子集合的问题。 We want the Status base class to have a StatusNotifications collection, which will be a collection of either the QuoteStatusNotification class, or the SystemStatusNotification class. 我们希望Status基类具有StatusNotifications集合,该集合将是QuoteStatusNotification类或SystemStatusNotification类的集合。 We couldn't work out how to create that StatusNotifications collection. 我们无法解决如何创建该StatusNotifications集合的问题。

From another thread here (see the second suggestion in the accepted answer), it looks like I might be able to do this with covariance, but I can't get my head round how to do it. 这里的另一个线程 (请参阅接受的答案中的第二个建议),看来我可以使用协方差来做到这一点,但是我无法理解如何做到这一点。

Anyone able to explain this? 任何人都可以解释吗?

Simple inheritance: 简单继承:

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
{
}

You can add a QuoteStatusNotificatio or SystemStatusNotification to the base class list 您可以将QuoteStatusNotificatio或SystemStatusNotification添加到基类列表

What you can do that is really neat in your xaml is provide different UI for the two classes in a list view for example. 您可以在xaml中真正做到的整洁,例如在列表视图中为两个类提供不同的UI。 See here: DataTemplate for each DataType in a GridViewColumn CellTemplate 参见此处: GridViewColumn CellTemplate中每个DataType的DataTemplate

For example: 例如:

<ListView ItemsSource="{Binding Statuses}">
    <ListView.Resources>
        <DataTemplate DataType="{x:Type viewModel:SystemStatus}">

        </DataTemplate>
        <DataTemplate DataType="{x:Type viewModel:QuoteStatus}">
        </DataTemplate>
    </ListView.Resources>
</ListView>

A bit more detail of what you're trying to do and may be able to help a bit more. 有关您要执行的操作的更多详细信息,也许可以提供更多帮助。

Create a base class that has the properties that are common across both types. 创建具有两种类型共有的属性的基类。 Then you can pass 然后你可以通过

List<StatusBaseClass> statuses;

You can put either type into this list. 您可以将任何一种类型放入此列表。

If it is a mixed list then you can get the individual types out by: 如果是混合列表,则可以通过以下方式获取各个类型:

var quoteStatuses = statuses.OfType<QuoteStatus>();
var systemStatuses = statuses.OfType<SystemStatus>();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在子接口中提供默认实现? - How do I provide a default implementation in a child interface? 如何定义泛型,泛型类型的属性? - How do I define a generic, generic typed property? 如何为自定义附加属性提供元素集合? - How do I provide a collection of elements to a custom attached property? 如何获得具有通用存储库模式的所有子集合? - How do I get all child collection with generic repository pattern? 如何在编译器确定类型的地方创建通用属性? - How do I create a generic property where the type is determined by the compiler? 如何使用反射调用泛型类的静态属性? - How do I call a static property of a generic class with reflection? 如何使用泛型类型的子类初始化泛型属性? - How to initialize a generic property with child class of generic type? 如何将子类分配给非泛型类中的泛型字段 - How do I assign a child class to a generic field in a non-generic class 如何为来自正文的模型上的属性提供自定义模型绑定器? - How do I provide a custom model binder for a property on a model from body? 使用 AutoMapper 如何在子集合中使用父属性? - Using AutoMapper how do I use a parent property in a child collection?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM