Answered by:
Bind DSL Model to WPF Treeview?

Question
-
Hi,
I have a simple model that represents class hierarchy:
MyModel (Domain model)
0...* Class (Domain class)
0...* Property (Domain class)
0...* Class (Domain class, "class can include other classes", these are stored in "ChildSourceObjects" role)
I want to bind each "Name" domain property to a treeview.
Treeview is specified like this:
<TreeView Grid.Column="1" Grid.Row="2" HorizontalAlignment="Stretch" Margin="13,6,0,0" <br/> Name="treeView1" VerticalAlignment="Stretch" Width="429" <br/> ItemsSource="{Binding Path=SourceObjects}" ItemTemplate="{StaticResource ObjectTemplate}" />
"SourceObjects" is the domain relationship's role where all classes are stored. The ItemTemplate named "ObjectTemplate" is specified like this:
<HierarchicalDataTemplate x:Key="ObjectTemplate" ItemsSource = "{Binding Path=ChildSourceObjects}"> <TextBlock Text="{Binding Path=Name}" FontWeight="Bold" FontSize="14"/> </HierarchicalDataTemplate>
With this code I am able to get the correct hierarchy of Classes in the treeview, but not the Properties in those classes.
Then I removed
ItemTemplate="{StaticResource ObjectTemplate}"
from the treeview and changed the templates like this:
<HierarchicalDataTemplate x:Key="ObjectTemplate" DataType="{x:Type dsl:SourceObject}" ItemsSource = "{Binding Path=ChildSourceObjects}"> <TextBlock Text="{Binding Path=Name}" FontWeight="Bold" FontSize="14"/> </HierarchicalDataTemplate> <HierarchicalDataTemplate x:Key="PropertyTemplate" DataType="{x:Type dsl:SourceProperty}" ItemsSource = "{Binding Path=SourceProperties}"> <TextBlock Text="{Binding Path=Name}" FontSize="10"/> </HierarchicalDataTemplate> <DataTemplate DataType="{x:Type dsl:SourceProperty}"> <TextBlock Text="{Binding Path=Name}"/> </DataTemplate>
I thought that this should work, but then even the class hierarchy is not shown in the treeview. I only element in treeview and it is the full name of the generated "SourceObject" class (namespace+class name).
Can anybody see what is wrong here?
BR,
Tomi
Thursday, March 17, 2011 8:59 PM
Answers
-
You should develop a property that merges your two collections of items (Classes and properties). This property could be a calculated property of the concept named Class.
Then, You use this new property to design your HierarchicalDataTemplate.
<TreeView ItemsSource="{Binding}"> <TreeView.Resources> <HierarchicalDataTemplate DataType="{x:Type dsl:SourceObject}" ItemsSource="{Binding Items}"> <TextBlock Text="{Binding Path=Name}" /> </HierarchicalDataTemplate> <DataTemplate DataType="{x:Type dsl:SourceProperty}" > <TextBlock Text="{Binding Path=Name}" /> </DataTemplate> </TreeView.Resources> </TreeView>
The property "Items" can be a collection of object (so not strongly typed) or maybe an abstract parent concept (NamedElement) that had a domain property Name.
Pascal
http://www.netfxfactory.org/- Proposed as answer by Jean-Marc PrieurMicrosoft employee Friday, March 18, 2011 9:17 AM
- Marked as answer by Tomi Airaksinen Friday, March 18, 2011 1:37 PM
Thursday, March 17, 2011 10:11 PM -
No, it's not necessary to create a tracking property (that is a "specialized" calculated property) or a calculated property ("To set up a calculated domain property, in the Properties window, set the Kind property to Calculated. You must then add custom code to implement the property").
- Create only a new partial class for the Class concept.
public partial class Class { public IEnumerable<ModelElement> Items { get { return this.ChildSourceObjects.Union(this.SourceProperties); } } }
Pascal
http://www.netfxfactory.org/- Marked as answer by Tomi Airaksinen Friday, March 18, 2011 1:37 PM
Friday, March 18, 2011 11:00 AM
All replies
-
You should develop a property that merges your two collections of items (Classes and properties). This property could be a calculated property of the concept named Class.
Then, You use this new property to design your HierarchicalDataTemplate.
<TreeView ItemsSource="{Binding}"> <TreeView.Resources> <HierarchicalDataTemplate DataType="{x:Type dsl:SourceObject}" ItemsSource="{Binding Items}"> <TextBlock Text="{Binding Path=Name}" /> </HierarchicalDataTemplate> <DataTemplate DataType="{x:Type dsl:SourceProperty}" > <TextBlock Text="{Binding Path=Name}" /> </DataTemplate> </TreeView.Resources> </TreeView>
The property "Items" can be a collection of object (so not strongly typed) or maybe an abstract parent concept (NamedElement) that had a domain property Name.
Pascal
http://www.netfxfactory.org/- Proposed as answer by Jean-Marc PrieurMicrosoft employee Friday, March 18, 2011 9:17 AM
- Marked as answer by Tomi Airaksinen Friday, March 18, 2011 1:37 PM
Thursday, March 17, 2011 10:11 PM -
Hi,
I'm new to DSL Toolkit, so can you point me to a right direction where I can find information about creating calculated properties in domain classes?
Or do you mean that I should add Tracking Property to the Class concept?
BR,
Tomi
Friday, March 18, 2011 10:20 AM -
No, it's not necessary to create a tracking property (that is a "specialized" calculated property) or a calculated property ("To set up a calculated domain property, in the Properties window, set the Kind property to Calculated. You must then add custom code to implement the property").
- Create only a new partial class for the Class concept.
public partial class Class { public IEnumerable<ModelElement> Items { get { return this.ChildSourceObjects.Union(this.SourceProperties); } } }
Pascal
http://www.netfxfactory.org/- Marked as answer by Tomi Airaksinen Friday, March 18, 2011 1:37 PM
Friday, March 18, 2011 11:00 AM -
Ahaa... It can be done that way also. Thank you for your quick reply.
BR,
Tomi
Friday, March 18, 2011 1:37 PM