beeker
beeker

Reputation: 810

Child of List<T> vs. BindingList<T> Behaving Differently When Attached to UltraWinGrid

I'm trying to create an in-memory representation of my data model. It is a "Payload" with "Sequences" and "Operations". A sequence can have other sequences below it and each sequence has lists of operations associated with the sequence.

Here is some mock data I am using for testing to give an idea:

public static void CreateMockData() //for making a car
{
    //parameters: SequenceNo (int), ParentSequenceNo (int?), SequenceType (enum), Description (string)
    Repository.SequencesList.Add(new Sequence(0, null, SequenceType.Standard, "Car assembly"));
    //parameters: ParentSequenceNo (int), OperationNo (int), Activity (string)
    Repository.OperationsList.Add(new Operation(0, 100, "Gather body parts"));
    Repository.OperationsList.Add(new Operation(0, 200, "Gather rims and tires"));

    Repository.SequencesList.Add(new Sequence(1, 0, SequenceType.Alternate, "Wheel assembly"));
    Repository.OperationsList.Add(new Operation(0, 300, "Mount tires on rims"));
    Repository.OperationsList.Add(new Operation(0, 400, "Inflate tires"));

    Repository.SequencesList.Add(new Sequence(2, 0, SequenceType.Alternate, "Body assembly"));
    Repository.OperationsList.Add(new Operation(2, 500, "Paint car body parts"));
    Repository.OperationsList.Add(new Operation(0, 600, "Bolt body parts to car body"));

    Repository.OperationsList.Add(new Operation(0, 700, "Install engine"));
        
    Repository.SequencesList.Add(new Sequence(3, 2, SequenceType.Parallel, "Battery charging and installation"));
    Repository.OperationsList.Add(new Operation(3, 800, "Charge battery"));
    Repository.OperationsList.Add(new Operation(3, 900, "Install battery"));

    Repository.OperationsList.Add(new Operation(0, 1000, "Bolt wheels to car"));
        
    Repository.OperationsList.Add(new Operation(0, 1100, "Do final inspection"));
    Repository.OperationsList.Add(new Operation(0, 1200, "Sign off inspection"));
}

The "Repository" class acts as a mock db, holding all the possible sequences and operations:

public static class Repository //mock db
{
    public static List<Sequence> SequencesList = new List<Sequence>(); //dumb list because it's a mock db, no need for binding stuff
    public static List<Operation> OperationsList = new List<Operation>(); //dumb list because it's a mock db, no need for binding stuff
}

Here are the "Sequence" and "Operation" classes

public enum SequenceType { Standard = 0, Alternate = 1, Parallel = 2 }

public class Sequence
{
    public Sequence() { }

    public Sequence(int SequenceNo, int? ParentSequenceNo, SequenceType Type, string Description)
    {
        this.SequenceNo = SequenceNo;
        this.ParentSequenceNo = ParentSequenceNo;
        this.Type = Type;
        this.Description = Description;
    }

    private Guid internalID = Guid.NewGuid();
    public Guid ID { get { return internalID; } }
    public int SequenceNo { get; set; }
    public int? ParentSequenceNo { get; set; } //if this is the main sequence then null, all others have a parent
    public SequenceType Type { get; set; }
    public string Description { get; set; }
    public int? BranchOperation { get; set; }
    public int? ReturnOperation { get; set; }

    //children
    //part of the problem here
    //if i change either of these list types to BindingList<T> they keep getting called over and over after binding to the grid...

    //public BindingList<Sequence> SubSequences { get { return Repository.SequencesList.FindAll(x => x.ParentSequenceNo == this.SequenceNo).ToBindingList(); }}
    //above will get called over and over...
    public List<Sequence> SubSequences { get { return Repository.SequencesList.FindAll(x => x.ParentSequenceNo == this.SequenceNo); } } 
    public List<Operation> Operations { get { return Repository.OperationsList.FindAll(x => x.ParentSequenceNo == this.SequenceNo); } }

    public void Save()
    {
        Repository.SequencesList[Repository.SequencesList.FindIndex(x => x.ID == this.ID)] = this;
    }

    public void Delete()
    {
        Repository.SequencesList[Repository.SequencesList.FindIndex(x => x.ID == this.ID)].Delete();
    }
}

public class Operation
{
    public Operation() { }

    public Operation(int ParentSequenceNo, int OperationNumber, string Activity) 
    {
        this.ParentSequenceNo = ParentSequenceNo;
        this.Activity = Activity;
    }

    private Guid internalID = Guid.NewGuid();
    public Guid ID { get { return internalID; } }
    public int ParentSequenceNo { get; set; }
    public int OperationNumber { get; set; }
    public string Activity { get; set; }
    public string OperationText { get; set; }
    public double LaborHours { get; set; } = 0;

    public void Save()
    {
        Repository.OperationsList[Repository.OperationsList.FindIndex(x => x.ID == this.ID)] = this;
    }

    public void Delete()
    {
        Repository.OperationsList[Repository.OperationsList.FindIndex(x => x.ID == this.ID)].Delete();
    }
}

The problem(s)...

I am using an Infragistics UltraWinGrid control.

  1. When I use a List<T> data type for the Sequence child lists, things work as I would expect, however, of the child bands (which are two different types, List<Sequence> and List<Operation>), only the columns for Sequence are shown. See image..
  2. When I use a BindingList<T> type for the child lists, they child binding lists keep getting called over and over just eating up the memory and the program never starts. This doesn't happen with a List<T> type.

Binding the list to the grid:

private void FrmMain_Load(object sender, EventArgs e)
{
    MockDataFiller.CreateMockData();
    List<Sequence> zeroSequenceList = new List<Sequence>();
    zeroSequenceList.Add(Repository.SequencesList.FirstOrDefault(x => x.SequenceNo == 0));
    gridSequences.DataSource = zeroSequenceList;
}

Example of bound grid with List (for Problem #1): enter image description here

My ultimate goal is to get this working with a BindingList (Problem 2) but, I'm really lost here. Any help to point me in the correct direction will be very much appreciated. Thanks.

Upvotes: 1

Views: 167

Answers (1)

Victor
Victor

Reputation: 8935

Gets or sets the max band depth. Grid will load upto MaxBandDepth number of bands. Note that you have to set the MaxBandDepth before binding the UltraGrid.

From the Infragistics documentation:

Use this property to force the grid to load upto only a certain number of bands. This can come in use where you have a recursive data relation where a table is related to itself and you only want the grid to drill down the band hierarchy only upto a certain level.

Default value for this property is 100 and range is 1-100 inclusive. Throws an ArgumentOutOfRange exception if set to a value below 1 or greater than 100.

Note: You must set the MaxBandDepth before binding the UltraGrid to a data source in order for this property to have any effect.

See MaxBandDepth Property

Upvotes: 1

Related Questions