Question

I have an object having the following structure:

 public class StockData
    {
        public string Name { get; set; }
        public double Change { get; set; }
        public DateTime LastUpdate { get; set; }
        public WorkflowStatus Status { get; set; }       
    }

The Workflow status enum is defined as following:

public enum WorkflowStatus
    {
        PendingCoverage,
        PendingCompliance,
        Approved,
        Rejected        
    }

Issue: I have a grid (wpf) which binds all StockData to it and I have set a grouping on the Status field. I want the groups to be appearing in the grid as it's defined in the order of WorkflowStatus enum. This works absolutely fine and data is grouped in the order as it's defined inside the enum i.e first group is Pendingcoverage and the last is Rejected.

Now I want to remove this enum and introduce an object graph instead of the enum..which means there will be a base class called WorkflowStatus and 4 derived class called PendingCoverage, PendingCompliance, Approved and Rejected. Each derived class will be overiding the ToString property and returning an appropriate string.

Now, this does't work. For some reason it's not able to establish which group should come first and which should come subsequently. Question is how will I implement IComparable in this scenario. Should I implement IComparable (or something else) on StockData or on each individual WorkflowStatus object, and yes then how? Also why does this work in the case of enum and not in the case of an object?

Was it helpful?

Solution

Create your base class and add an abstract Order property to it that all sub classes must implement. Basically an integer which specifies their ordering.

You can also implement IComparable on your abstract class so that if compares objects based on their order property.

public abstract class WorkStatus : IComparable<WorkStatus> {
    public abstract int Order { get; } 

    public int CompareTo(WorkStatus w)
    {
        if(w.Order < this.Order)
         return 1;
        if(w.Order > this.Order)
         return -1;
        return 0;
    }
}

For each implementation, give them a different Order value.

public class FirstStatus : WorkStatus {
   public override int Order {get { return 1; } }
}

public class SecondStatus : WorkStatus {
   public override int Order { get { return 2; } }
}

Assuming your WPF grid is just applying a standard OrderBy query, then if should work as follows.

//LINQPAD SNIPPET
void Main()
{
    List<WorkStatus> list = new List<WorkStatus>();

    list.Add(new SecondStatus()); //out of order initially.
    list.Add(new FirstStatus());

    Console.WriteLine(list.OrderBy(x => x));


}

OTHER TIPS

I'm confused as to why IComparable is required here. You have two problems. One is getting a sorted list, the other is getting the appropriate graph:

// Takes a work status and returns the appropriate graph.
static GenericBaseGraphClass GetGraph(WorkStatus input)
{
    select(input.Status)
    {
        // Concrete derived classes go here.
    }
}

// Test data.
var someWork = new List<WorkStatus>()
{
    new SecondStatus(),
    new FirstStatus()
};

// Sort it.
var sortedWork = someWork.Sort((x,y) => x.Status > y.Status);

// Get your object graphs.
var objectGraphs = sortedWork.Select(x => GetGraph(x.Status))
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top