Ordered lists

Ordered lists

Old forum URL: forums.lhotka.net/forums/t/1366.aspx


ajj3085 posted on Monday, October 02, 2006

Hi,

Has anyone created a business list in which the order of the items in the collection mattered?  I have a list which needs to be always sorted in the same way, even between saving and loading.  The user may also reorder the items in the collection manually.

What I've done is given each item in the list a position which is part of its state, so that it can save and load.  As items are inserted or removed, the collection just runs though and assignes a value based on the index of each item.

On the UI side, I'll use SortedBindingList and force a sort on this position value.

How have others handled this?

Thanks
Andy

Henrik replied on Tuesday, October 03, 2006

Hi Andy

I've done exactly what you desribe, in several applications, with success, so I recommend this as the way to go.

/Henrik

ajj3085 replied on Tuesday, October 03, 2006

Great, thanks for the feedback, glad to know I'm not offbase.

JHurrell replied on Tuesday, October 03, 2006

I've also done it this way in the past. Your question did make me think a little and I'd like to share some of my thoughts.

In the past, my child objects have exposed a property called Position. One thing I didn't do is make this property public internal in scope. I think this is important because you want you collection to be able to change the Position but NOT allow the UI to do so.

The only time a child's Position would change would under the following circumstances:
Here's what I'm thinking:

public class ChildObject
{
    public int _position = -1;
    public internal int Position { get; set; }
}

public class ParentCollection
{
    public void MoveUp(int index)
    {
        if(index > 0 && List.Count > 1)
        {
            // Swap elements [index] and [index - 1].
            // Update Position on elements [index] and [index - 1].
        }
    }
   
    public void MoveDown(int index)
    {
        if(index < List.Count - 1 && List.Count > 1)
        {
            // Swap elements [index] and [index - 1].
            // Update Position on elements [index] and [index - 1].
        }
    }
   
    public ChildObject Insert(ChildObject child)
    {
        // Add child to end of list and set Position.
    }

    public void Remove(ChildObject child)
    {
        // Determine [index] of child.
        // Remove child.
        // Update Position for each item >= [index]
    }

    public void RemoveAt(int index)
    {
        // Remove child at
[index].
        // Update Position for each item <= [index]
    }
}


Not that there's anything special about the pseudo-code, but I think the important things to base a best practice on are the following:
Is this about what everyone else is thinking?

- John

ajj3085 replied on Tuesday, October 03, 2006

John,

You were able to answer another question for me.. thanks for the psuedo code which shows where MoveUp and MoveDown live. 

My Position property is public get, but internal set.  My reasoning is this; the collection and objects manage their positions, but actually displaying them in the right order is the job of the UI.  It seems like keeping the internal list sorted would be more complex than wrapping my BLB in a SortedBindingList and forcing a sort.  After all, there may be a UI that doesn't care to actually display them in the order they define for some reason.

I did something similar to your implementation, but I overrode InsertItem and RemoveItem and SetItem.  After running the base method, I call a method which just blindly sets the position on each child object (after turning off events of course). 

Andy

Copyright (c) Marimer LLC