Reputation: 73
I have a list of Rule class which needs to be bound to Treeview but hierarchy of Treeview nodes should be like this
IF
--IF2
--ElseIF
----IF3
--Else
----IF4
Here is the Rule class
public class Rule
{
private List<RuleTag> elseIf = new List<RuleTag>();
public RuleTag IF { get; set; }
public RuleTag Else { get; set; }
public List<RuleTag> ElseIf
{
get { return elseIf; }
}
public Rule() { }
}
And the RuleTag is defined below
public class RuleTag
{
private List<Rule> children = new List<Rule>();
public List<Rule> Children
{
get { return children; }
set { children = value; }
}
public RuleTag() { }
}
In the example above IF2 is a member IF.Children, ElseIF is Rule.ElseIF[0] (If there are more than one ElseIf in array all need to be displayed) and IF3 is a member of Rule.ElseIf[0].Children and IF4 is a member of Rule.Else.Children
I've experimented with HierarchicalDataTemplate but I'm only able to bind to children of IF and unable to display Else and ElseIF as children
Here is my XAML
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type TangoRules:Rule}" ItemsSource="{Binding IF.Children}">
<TextBlock Text="IF" />
</HierarchicalDataTemplate>
</TreeView.Resources>
Upvotes: 1
Views: 537
Reputation: 73
I solved it using CompositeCollection by modifying the Rule class like below
public class Rule : INotifyPropertyChanged
{
private ObservableCollection<RuleTag> elseIf = new ObservableCollection<RuleTag>();
private RuleTag _else;
private CompositeCollection children = new CompositeCollection();
public RuleTag IF { get; set; }
public RuleTag Else
{
get { return _else; }
set
{
_else = value;
OnPropertyChanged("Children");
}
}
public ObservableCollection<RuleTag> ElseIf
{
get { return elseIf; }
}
public CompositeCollection Children
{
get
{
children.Clear();
children.Add(new CollectionContainer() { Collection = IF.Children });
children.Add(new CollectionContainer() { Collection = ElseIf });
if (Else != null)
children.Add(Else);
return children;
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string name)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
}
Note that I've now also implemented the INotifyPropertyChanged interface that is because the else part in class wasn't a collection. Now when Rule class was instantiated if Else was empty it wasn't added to the CompositeCollection but if it's set later on, I would notify all the observers of CompositeCollection that this property is changed. Besides I've made all my lists e.g. IF.Childre, List observablecollection
Upvotes: 0
Reputation: 873
Try Hierarchical Datatemplate with two levels as:
<HierarchicalDataTemplate ItemsSource="{Binding RuleCollection}">
<TextBlock Text="{Binding IF}" />
<HierarchicalDataTemplate.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Children}">
<HierarchicalDataTemplate.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}" />
</DataTemplate>
</HierarchicalDataTemplate.ItemTemplate>
</HierarchicalDataTemplate>
</HierarchicalDataTemplate.ItemTemplate>
</HierarchicalDataTemplate>
Upvotes: 0