简体   繁体   中英

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. 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)...

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.

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). 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. Depending on what value the user chooses in the dropdown, the Statuses property would contain either the _quoteStatuses collection, or the _systemStatuses collection.

We did that by creating a base Status class, and having the QuoteStatus and SystemStatus classes inherit from it. 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. We couldn't work out how to create that StatusNotifications collection.

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

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. See here: DataTemplate for each DataType in a GridViewColumn CellTemplate

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>();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM