mirror of
https://github.com/gui-cs/Terminal.Gui.git
synced 2025-12-26 15:57:56 +01:00
added docs on generic treeview
This commit is contained in:
@@ -25,6 +25,8 @@ namespace UICatalog.Scenarios {
|
||||
new MenuBarItem ("_Scenarios", new MenuItem [] {
|
||||
new MenuItem ("_Simple Nodes", "", () => LoadSimpleNodes()),
|
||||
new MenuItem ("_Rooms", "", () => LoadRooms()),
|
||||
new MenuItem ("_Armies With Builder", "", () => LoadArmies(false)),
|
||||
new MenuItem ("_Armies With Delegate", "", () => LoadArmies(true)),
|
||||
}),
|
||||
});
|
||||
|
||||
@@ -101,6 +103,88 @@ namespace UICatalog.Scenarios {
|
||||
currentTree = tree;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private abstract class GameObject
|
||||
{
|
||||
|
||||
}
|
||||
private class Army : GameObject
|
||||
{
|
||||
public string Designation {get;set;}
|
||||
public List<Unit> Units {get;set;}
|
||||
|
||||
|
||||
public override string ToString ()
|
||||
{
|
||||
return Designation;
|
||||
}
|
||||
}
|
||||
|
||||
private class Unit : GameObject
|
||||
{
|
||||
public string Name {get;set;}
|
||||
public override string ToString ()
|
||||
{
|
||||
return Name;
|
||||
}
|
||||
}
|
||||
|
||||
private class GameObjectTreeBuilder : ITreeBuilder<GameObject> {
|
||||
public bool SupportsCanExpand => true;
|
||||
|
||||
public bool CanExpand (GameObject model)
|
||||
{
|
||||
return model is Army;
|
||||
}
|
||||
|
||||
public IEnumerable<GameObject> GetChildren (GameObject model)
|
||||
{
|
||||
if(model is Army a)
|
||||
return a.Units;
|
||||
|
||||
return Enumerable.Empty<GameObject>();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void LoadArmies(bool useDelegate)
|
||||
{
|
||||
var army1 = new Army()
|
||||
{
|
||||
Designation = "3rd Infantry",
|
||||
Units = new List<Unit>{
|
||||
new Unit(){Name = "Orc"},
|
||||
new Unit(){Name = "Troll"},
|
||||
new Unit(){Name = "Goblin"},
|
||||
}
|
||||
};
|
||||
|
||||
if(currentTree != null)
|
||||
Win.Remove(currentTree);
|
||||
|
||||
var tree = new TreeView<GameObject>()
|
||||
{
|
||||
X = 0,
|
||||
Y = 0,
|
||||
Width = 40,
|
||||
Height = 20
|
||||
};
|
||||
|
||||
if(useDelegate){
|
||||
tree.TreeBuilder = new DelegateTreeBuilder<GameObject>((o)=>o is Army a ? a.Units : Enumerable.Empty<GameObject>());
|
||||
}
|
||||
else{
|
||||
tree.TreeBuilder = new GameObjectTreeBuilder();
|
||||
}
|
||||
|
||||
Win.Add(tree);
|
||||
|
||||
tree.AddObject(army1);
|
||||
|
||||
currentTree = tree;
|
||||
}
|
||||
|
||||
private void Quit ()
|
||||
{
|
||||
Application.RequestStop ();
|
||||
|
||||
@@ -26,6 +26,7 @@ namespace UICatalog.Scenarios {
|
||||
private MenuItem miColoredSymbols;
|
||||
private MenuItem miInvertSymbols;
|
||||
private MenuItem miUnicodeSymbols;
|
||||
private MenuItem miFullPaths;
|
||||
private Terminal.Gui.Attribute green;
|
||||
private Terminal.Gui.Attribute red;
|
||||
|
||||
@@ -52,6 +53,7 @@ namespace UICatalog.Scenarios {
|
||||
null /*separator*/,
|
||||
miColoredSymbols = new MenuItem ("_ColoredSymbols", "", () => ShowColoredExpandableSymbols()){Checked = false, CheckType = MenuItemCheckStyle.Checked},
|
||||
miInvertSymbols = new MenuItem ("_InvertSymbols", "", () => InvertExpandableSymbols()){Checked = false, CheckType = MenuItemCheckStyle.Checked},
|
||||
miFullPaths = new MenuItem ("_FullPaths", "", () => SetFullName()){Checked = false, CheckType = MenuItemCheckStyle.Checked},
|
||||
}),
|
||||
});
|
||||
Top.Add (menu);
|
||||
@@ -171,6 +173,16 @@ namespace UICatalog.Scenarios {
|
||||
treeViewNodes.SetNeedsDisplay();
|
||||
}
|
||||
|
||||
private void SetFullName()
|
||||
{
|
||||
miFullPaths.Checked = !miFullPaths.Checked;
|
||||
|
||||
if(miFullPaths.Checked)
|
||||
treeViewFiles.AspectGetter = (f)=>f.FullName;
|
||||
else
|
||||
treeViewFiles.AspectGetter = (f)=>f.Name;
|
||||
}
|
||||
|
||||
|
||||
private ITreeNode CreateSimpleRoot ()
|
||||
{
|
||||
|
||||
@@ -96,10 +96,111 @@ tree.AddObject(myHouse);
|
||||
|
||||
```
|
||||
|
||||
Alternatively you can simply tell the tree how the objects relate to one another by implementing `ITreeBuilder`. This is a good option if you don't have control of the data objects you are working with:
|
||||
|
||||
```
|
||||
TODO
|
||||
```
|
||||
Alternatively you can simply tell the tree how the objects relate to one another by implementing `ITreeBuilder<T>`. This is a good option if you don't have control of the data objects you are working with.
|
||||
|
||||
## TreeView<T>
|
||||
|
||||
The generic `Treeview<T>` allows you to store any object hierarchy where nodes implement Type T. For example if you are working with `DirectoryInfo` and `FileInfo` objects then you could create a `TreeView<FileSystemInfo>`. If you don't have a shared interface/base class for all nodes you can still declare a `TreeView<object>`.
|
||||
|
||||
In order to use `TreeView<T>` you need to tell the tree how objects relate to one another (who are children of who). To do this you must provide an `ITreeBuilder<T>`.
|
||||
|
||||
|
||||
### Implementing ITreeBuilder<T>
|
||||
|
||||
Consider a simple data model that already exists in your program:
|
||||
|
||||
```csharp
|
||||
private abstract class GameObject
|
||||
{
|
||||
|
||||
}
|
||||
private class Army : GameObject
|
||||
{
|
||||
public string Designation {get;set;}
|
||||
public List<Unit> Units {get;set;}
|
||||
|
||||
|
||||
public override string ToString ()
|
||||
{
|
||||
return Designation;
|
||||
}
|
||||
}
|
||||
|
||||
private class Unit : GameObject
|
||||
{
|
||||
public string Name {get;set;}
|
||||
public override string ToString ()
|
||||
{
|
||||
return Name;
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
An `ITreeBuilder<T>` for these classes might look like:
|
||||
|
||||
```csharp
|
||||
|
||||
private class GameObjectTreeBuilder : ITreeBuilder<GameObject> {
|
||||
public bool SupportsCanExpand => true;
|
||||
|
||||
public bool CanExpand (GameObject model)
|
||||
{
|
||||
return model is Army;
|
||||
}
|
||||
|
||||
public IEnumerable<GameObject> GetChildren (GameObject model)
|
||||
{
|
||||
if(model is Army a)
|
||||
return a.Units;
|
||||
|
||||
return Enumerable.Empty<GameObject>();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
To use the builder in a tree you would use:
|
||||
|
||||
```
|
||||
var army1 = new Army()
|
||||
{
|
||||
Designation = "3rd Infantry",
|
||||
Units = new List<Unit>{
|
||||
new Unit(){Name = "Orc"},
|
||||
new Unit(){Name = "Troll"},
|
||||
new Unit(){Name = "Goblin"},
|
||||
}
|
||||
};
|
||||
|
||||
var tree = new TreeView<GameObject>()
|
||||
{
|
||||
X = 0,
|
||||
Y = 0,
|
||||
Width = 40,
|
||||
Height = 20,
|
||||
TreeBuilder = new GameObjectTreeBuilder()
|
||||
};
|
||||
|
||||
|
||||
tree.AddObject(army1);
|
||||
```
|
||||
|
||||
Alternatively you can use `DelegateTreeBuilder<T>` instead of implementing your own `ITreeBuilder<T>`. For example:
|
||||
|
||||
```
|
||||
tree.TreeBuilder = new DelegateTreeBuilder<GameObject>(
|
||||
(o)=>o is Army a ? a.Units
|
||||
: Enumerable.Empty<GameObject>());
|
||||
```
|
||||
|
||||
## Node Text and ToString
|
||||
|
||||
The default behaviour of TreeView is to use the `ToString` method on the objects for rendering. You can customise this by changing the `AspectGetter`. For example:
|
||||
|
||||
```
|
||||
treeViewFiles.AspectGetter = (f)=>f.FullName;
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user