I use Eto’s TreeGridView and display a single column that uses Eto’s CustomCell. This seems to render correctly until the tree is large enough so that it gets a scroll bar. Once I start scrolling to view the tree, the cells can be rendered in a different order than they exist in the DataStore.
Example:
I created a tree to display two different types of Nodes, A and B. The tree’s datastore is initialized:
public class Root : ITreeGridStore<Node>, ITreeGridItem
{
List<Node> nodes;
public Root()
{
nodes = new List<Node>();
for (int i = 0; i < 10; i++)
{
nodes.Add(new NodeA(this));
nodes.Add(new NodeA(this));
nodes.Add(new NodeB(this));
nodes.Add(new NodeB(this));
}
}
where the column is set up to display the cell via:
public class NodeA : Node
{
public NodeA(ITreeGridItem p) : base(p) { }
public override Control CreateCell(CellEventArgs a)
{
return new Label { Text = "A A A", BackgroundColor = Colors.Blue };
}
}
public class NodeB : Node
{
public NodeB(ITreeGridItem p) : base(p) { }
public override Control CreateCell(CellEventArgs a)
{
return new Label { Text = "B B B", BackgroundColor = Colors.Yellow };
}
}
This shows how the cells can be created/?displayed in a different order than the datastore when the tree is scrolled up and down:
The problem you are having is because cells are reused, and you are not configuring the cell properly. During your ConfigureCell, you need to change the properties of the existing control (which is passed in as a parameter) to match the new args.Item.
Note that setting the DataContext only works if you are using MVVM bindings with your controls.
I have a related question to this post. I have an EtoTreeGridView which uses MVVM bindings.
When I scroll down to view all the cells in the Tree, the cells initially not shown are not loaded until some action occurs such as clicking on the expander button for a parent cell.
could you be a bit more explicit on what you mean by “…change the properties of the existing control (which is passed in as a parameter) to match the new args.Item …”???
I am having the same issue and no clue on what is going on.
This is my current code in OnCreateCell override.
protected override Control OnCreateCell(CellEventArgs args)
{
string text = "???";
if (args.Item is TreeGridItem treeGridItem)
{
if (treeGridItem.Values[args.Column] is string stringValue)
{
if (treeGridItem.Children != null &&
!(treeGridItem.Values[args.Column + 1] is AFPropertyBaseType baseType))
{
text = stringValue + " (" + treeGridItem.Children.Count.ToString() + ")";
}
else
{
text = stringValue;
}
}
else if (treeGridItem.Values[args.Column] is Tuple<string, int> tuple)
{
text = tuple.Item1 + " (" + tuple.Item2.ToString() + ")";
}
}
else if (args.Item is GridItem item)
{
if (item.Values[args.Column] is string stringValue)
{
text = stringValue;
}
}
if (args.GridColumn.Editable)
{
TextBox textBox = new TextBox
{
Height = 18,
ShowBorder = false,
TextAlignment = TextAlignment.Left,
};
textBox.Text = text;
textBox.TextChanged += new EventHandler<EventArgs>(this.OnTextChanged);
return textBox;
}
else
{
Label label = new Label
{
Height = 18,
Text = text,
TextAlignment = TextAlignment.Left,
VerticalAlignment = VerticalAlignment.Center,
};
label.MouseDown += new EventHandler<MouseEventArgs>(this.OnLabelMouseDown);
return label;
}
}