Hello, In our application we have a XamDataGrid with dynamic nested columns. We've set up the backing data classes as the following:
class Parent { public Parent(string name) { Name = name; } public string Name { get; set; } public List<Child> Children { get; set; } = new List<Child>(); } class Child { public string Name { get; set; } }
and we setup the fields like the following:
var unboundField = new Field() { BindingType = BindingType.UseAlternateBinding, AlternateBinding = new Binding() { Path = new PropertyPath("Parents[parentIndex].Children[{childIndex}].[{property.PropertyName}]") } };
and then the data is created the following way:
public VM() { var p1 = new Parent(); var p2 = new Parent(); var c1 = new Child(); var c2 = new Child(); var children = new List<Child>() { c1, c2 }; p1.Children = children; Parents = new List<Parent>() { p1, p2 }; }
I want to display a column for the parents name and then a column for each child object in the list of Parent.ChildrenThe issue comes from the alternatebinding string because it's essentially hardcoded - if the children property of parent is an empty list (a valid use case) then trying to access the property of the child object causes an exception. Is there a way to check for the contents of the children list when fetching the value?
Hello Shael,
Getting a binding expression error in this case is expected, as if the Parents or Children collection that you are alternate binding to is empty, this would internally cause an IndexOutOfRange exception for the values you are passing as parentIndex or childIndex.
Being that you are creating a Field per item in this case, I would recommend that you check the item prior to creating the Field to ensure the Children collection is populated as this will avoid binding errors / exceptions.
Hi Andrew, Thanks for the response.Unfortunately the data isn't setup when creating the fields so we can't check before creating the fields. Is there a way to check evaluating the binding expression?
Thank you for your update on this matter, but I’m rather confused by it?
If your Fields and alternate bindings are being set up before the data even arrives, then where are the variables like parentIndex and childIndex coming from in your code? To me, it seems like if you are going to set up bindings that depend on the data items being there, you should await those data items being there, because these bindings will fail if the data is not there. Perhaps it would be better to wait until your data is ready before setting up the Fields as I am not aware of a way to check the evaluation of the binding expression after it has already been applied.
Sorry for the confusion, the indexes are simple counters. However, I was able to refactor to allow for the data to be setup completely before setting up the bindings. The issue I'm having now is that not all cells in a column are populated and those cells will throw an exception. The binding is at the field level. Here's an example of how our grid is setup - in this case the most amount of childs a parent has is 3 so we have 3 columns for each parent to display the children's names. The cells outlined in red do not have any values and are throwing exceptions.
I have a few questions for you based on your most recent update. Can you please answer the following?
I ask these, as if the number of children in this case is fixed, or if the greatest number of children is known, then you should be able to do this with a set number of Fields in the grid that also don’t necessarily need to be alternate-bound, as this will not be as performant as name-binding them. The next step will depend on your answers to the two questions above, though.
I have been investigating into this requirement further, and I think the best recommendation I can make here is to put together a DataTable that is more representative of your data structure, since it seems that some child columns will be populated, and others won’t. If you find out the maximum number of columns that you need, this will be the number of columns of the child DataTable so that you can populate the child band with the correct number of columns.
Doing this, you will be able to do away with the usage of the AlternateBinding because the grid can auto-generate its columns based on what is in the parent and child DataTable. I have put together a mock data source and sample that demonstrates this, and I am attaching it here. I hope it helps you.
Please let me know if you have any other questions or concerns on this matter.
XDGHierarchicalDataTableTest.zip
1. Unfortunately no, technically there is no limit to how many children a parent can have.
2. We're getting a ArgumentOutOfRangeException which makes sense given the binding is Parents[parentIndex].Children[{childIndex}].[{propertyPath}]. Trying to access the childIndex element of Children (which is an empty list) will throw the exception