Hey there,
Here is the simplified code I use (the board screws code pasting up pretty much - so just c/p it into VS):
static void Main(string[] args)
{
A root = new A { Config = "my root", Filters = new List<B>() };
B filter = new B { Filter = "foo", Items = new List<C>() };
C soloItem = new C { Name = "solo" };
C parent = new C { Name = "parent", Children = new List<C>() };
C child1 = new C { Name = "child1", Children = new List<C>() };
C child2 = new C { Name = "child2" };
C otherSolo = new C { Name = "solo2" };
filter.Items.Add(parent);
filter.Items.Add(child1);
filter.Items.Add(child2);
filter.Items.Add(soloItem);
filter.Items.Add(otherSolo);
parent.Children.Add(child1);
child1.Parent = parent;
child1.Children.Add(child2);
child2.Parent = child1;
/*
* my root
* --foo
* ----solo
* ----child1
* ------child2
* ----solo2
*/
}
public class A
public String Config { get; set; }
public List<B> Filters { get; set; }
public class B
public String Filter { get; set; }
public List<C> Items { get; set; }
public List<C> DisplayItems
get
return Items.Where(x => x.Parent == null).ToList();
public class C
public String Name { get; set; }
public C Parent { get; set; }
public List<C> Children { get; set; }
A is the root and has a collection of B.B has a collection of ALL C.C can have a Parent C and a collection of Child C.When displaying B, I want only Cs to appear which do not have a Parent. But those shall appear as Children of Cs.To do so, B provides a wrapped property (DisplayItems) returing the filtered collection.
What i have so far is:
<ig:XamDataTree.GlobalNodeLayouts> <ig:NodeLayout TargetTypeName="A" Key="a"/> <ig:NodeLayout TargetTypeName="B" Key="b"/> <ig:NodeLayout TargetTypeName="C" Key="c"/> </ig:XamDataTree.GlobalNodeLayouts>
I tried with nested NodeLayouts and Assigning keys... but the Result was pretty useless...
Can u help?
Hi Konstantin,
Part of the issue may be that your B class has two collections. Items and DisplayItems. With the current way class B is defined, only the Items collection is going to be used, not the DisplayItems collection. This is because it appears first in the class. GlobalNodeLayouts will look for the first collection in the class and use that for children. If you want to directly specify which collection to use, you need to use XamDataTree.NodeLayouts instead. This lets you specify exactly how to display the hiearchy. For example:
<!-- This ItemsSource binding is to the root nodes. "Config" is the display property on the root node class. --> <ig:XamDataTree ItemsSource="{Binding}" DisplayMemberPath="Config"> <ig:XamDataTree.NodeLayouts> <!-- This NodeLayout is for the child nodes of the root nodes, so class B. "Filters" is the collection name in class A where B nodes are located. The DisplayMemberPath is set to class B's display name property. --> <ig:NodeLayout Key="Filters" DisplayMemberPath="Filter"> <ig:NodeLayout.NodeLayouts> <!-- This NodeLayout is for the child nodes of class B. "DisplayItems" is collection name in class B where C nodes are located. --> <ig:NodeLayout Key="DisplayItems" DisplayMemberPath="Name"/> </ig:NodeLayout.NodeLayouts> </ig:NodeLayout> </ig:XamDataTree.NodeLayouts>
Now, I'm still a little confused about what you are actually trying to accomplish. Right now your DisplayItems collection is going to return all C nodes that do not have a parent. So 'parent', 'solo' and 'solo2' are going to be displayed under B(foo). This is what the hierarchy will look like:
* my root* --foo* ----parent* ----solo* ----solo2
I have attached a sample that demonstrates this. Can you let me know what the expected tree is supposed to look like? I can adjust the sample to produce those results.
first step done.
parent has children - those are not diplayed.
each child may have 0..n children in any depth.
If I use a GlobalNodeLayout the tree is build um recursivly - if i specify the nodes explicitly using the NodeLayout I seem not to get any children...
Yeah, using NodeLayouts instead of GlobalNodeLayouts means you will have to know the depth of your tree ahead of time. You will have to switch back to GlobalNodeLayouts. But this takes us back to the issue where DisplayItems is not getting used. To resolve this, change the order of the properties in your B class so that DisplayItems is before Items. I updated the sample to do this so now you see the children under parent.
What you Need to do, is add a key to the nodelayout. Also add a global layout for the specific type, but providing a key with the same value as in the concrete layout:
e.g.
<ig:XamDataTree.NodeLayouts>
<ig:NodeLayout Key="Foo">
<ig:NodeLayout.NodeLayouts> <ig:NodeLayout Key="root"/>
</ig:NodeLayout.NodeLayouts>
</ig:NodeLayout>
</ig:XamDataTree.NodeLayouts>
<ig:XamDataTree.GlobalNodeLayouts>
<ig:NodeLayout TargetTypeName="SomeClass" Key="root"/>
</ig:XamDataTree.GlobalNodeLayouts>
P.S. pasting code on this board is a pain...