Search code examples
c#winformsdevexpressdevexpress-windows-ui

Reorder LayoutControlGroups inside another LayoutControlGroup on runtime


I've got LayoutControlGroup with few other LayoutControlGroups inside.

What I need to do is to reorder them into specific order on runtime.

For example, when form shows up I've got those groups in such order:

[Group0]
[Group1]
[Group2]
[Group3]
[Group4]

And then I get some data from DB and need to reorder groups according to that data, for example just reverse the order:

[Group4]
[Group3]
[Group2]
[Group1]
[Group0]

What I tried already:

List<BaseLayoutItem> currentOrder = lcgParentGroup.Items.Cast<object>().Where(c => c is BaseLayoutItem).Cast<BaseLayoutItem>().Where(c => c.Name.StartsWith("lcgInnerGroup") && char.IsDigit(c.Name.Last())).ToList();
currentOrder.Sort((x, y) => System.Collections.Comparer.Default.Compare(x.Location.Y, y.Location.Y));

// Example order
List<BaseLayoutItem> requiredOrder = new List<BaseLayoutItem>(currentOrder);
requiredOrder.Reverse();

for (int i = 1; i < requiredOrder.Count; ++i)
{
    // I just move every group after every relative group.
    BaseLayoutItem relative = lcgParentGroup.Items.FindByName(requiredOrder[i - 1].Name);

    DevExpress.XtraLayout.Customization.LayoutItemDragController dragController = new DevExpress.XtraLayout.Customization.LayoutItemDragController(requiredOrder[i], relative, MoveType.Outside, InsertLocation.After, LayoutType.Vertical);
    bool result = requiredOrder[i].Move(dragController);    
}

However everytime the result is false.

Is there any other way to do it?


Solution

  • I've figured it out. The groups have to be Visibile (Visibility.Always) to move them. Dunno why.

    The solution pseudo-code:

    try
    {
        groups.BeginUpdate();
    
        List<object> dataFromDB = ...;
    
        // Znamy aktualną kolejność grup
        List<BaseLayoutItem> currentOrder = groups.Items.Cast<object>().Where(c => c is BaseLayoutItem).Cast<BaseLayoutItem>().ToList();
    
        // Sort as visibile in form
        currentOrder.Sort((x, y) => System.Collections.Comparer.Default.Compare(x.Location.Y, y.Location.Y));
    
        // Save old visibilities
        LayoutVisibility[] allVisibilities = currentOrder.Select(x => x.Visibility).ToArray();
        currentOrder.ForEach(x => x.Visibility = LayoutVisibility.Always);
    
        List<BaseLayoutItem> requiredOrder = ...; // prepare required order
    
        // Make requiredOrder[0] topmost group
    
        // Move
        for (int i = 1; i < requiredOrder.Count; ++i)
        {
            BaseLayoutItem relative = groups.Items.FindByName(requiredOrder[i - 1].Name);
            BaseLayoutItem toMove = groups.Items.FindByName(requiredOrder[i].Name);
    
            toMove.Move(relative, InsertType.Bottom);
        }
    
        // Restore visibilities
        for (int i = 0; i < currentOrder.Count; ++i)
        {
            currentOrder[i].Visibility = allVisibilities[i];
        }
    
    }
    finally
    {
        groups.EndUpdate();
    }