Any ideas on how to make TreeView show changes to the order of items in a List<T>? #4009
-
I have a Branch class that holds child branches: class Branch
{
public string Id;
public List<Branch>? Branches { get; set; }
public Branch? Parent { get; set; }
} I have a TreeView that uses the following treebuilder: _treeView.TreeBuilder = new DelegateTreeBuilder<Branch>(
branch => branch is not null
? branch.Branches
: []); I move the selected branch up or down in its List with: private void ShiftItem(int direction) //-1 for up, 1 for down
{
var selectedBranch = _treeView.SelectedObject;
var parent = selectedBranch.Parent;
var list = parent.Branches;
var currentIndex = list.IndexOf(selectedBranch);
var newIndex = currentIndex + direction;
if (!IsValidIndex(list, newIndex)) return;
list.RemoveAt(currentIndex);
list.Insert(newIndex, selectedBranch);
_treeView.RefreshObject(parent);
}
private static bool IsValidIndex(List<Branch> list, int index) => (index >= 0 && index < list.Count); Even after calling RefreshObject on the parent, the items are still displayed in the original order. I've verified that the items in the list have been correctly re-ordered. I feel like I'm probably doing something wrong or missing something? I'm using |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 6 replies
-
Hmn, I am not at computer at the moment but the first thing to try would be adding Equality members and GetHashCode for your branch class. Have you tried the The internal data model for TreeView branches is Dictionary so ordering may somehow have issue... I will need to investigate. If you simply remove the objects and refresh do they disappear? |
Beta Was this translation helpful? Give feedback.
-
Here is repro, equality wont help. Seems the reordering isnt supported at the moment. After the first state is gotten a branch tracks new and removed children but uses a Dictionary to do so which isn't ordered. Since the objects were there before and still there its probably just adding new ones at the end.
using Terminal.Gui;
Application.Init();
var tv = new TreeView<Branch>(new DelegateTreeBuilder<Branch>(
branch => branch is not null
? branch.Branches?.ToArray() ?? []
: []))
{
Width= Dim.Fill(),
Height = Dim.Fill()
};
tv.AddObject(new Branch()
{
Id = "root",
Branches = new List<Branch>()
{
new Branch(){Id = "A"},
new Branch(){Id = "B"},
new Branch(){Id = "C"},
new Branch(){Id = "D"}
}
});
Random r = new Random();
tv.ObjectActivated += (sender, e) =>
{
e.ActivatedObject.Branches = e.ActivatedObject.Branches?.OrderBy(o => r.Next()).ToList();
// new goes at end even though inserted 0
e.ActivatedObject.Branches.Insert(0,new Branch(){Id="new"});
tv.RefreshObject(e.ActivatedObject,true);
};
var w = new Window();
w.Add(tv);
Application.Run(w);
Application.Shutdown();
class Branch
{
public string Id;
public List<Branch>? Branches { get; set; }
public Branch? Parent { get; set; }
public override string ToString()
{
return Id;
}
public override bool Equals(object? obj)
{
if (obj is Branch other)
{
return Id == other.Id;
}
return false;
}
public override int GetHashCode()
{
return Id.GetHashCode();
}
} |
Beta Was this translation helpful? Give feedback.
-
I have updated v2 to always respect the order of children provided in: #4015 |
Beta Was this translation helpful? Give feedback.
I have updated v2 to always respect the order of children provided in: #4015