Thanks in advance,
I want to bind an observable collection to a TreeView in WPF such that it should display the each TreeView Node as a CountryType. The TreeView is bound to this collection from code behind.
Here's the code :
public partial class MyUserControl: UserControl
{
public ObservableCollection<Person> myList { get; set; }
public IEnumerable<PersonViewModel> PersonViewModelList { get; set; }
public MyUserControl()
{
InitializeComponent();
PopulateCollection();
DataContext = this;
}
private void PopulateCollection()
{
myList = new ObservableCollection<Person>()
{
new Person{ Name="Name 1", Age=21, CountryType = CountryList.India},
new Person{ Name="Name 2", Age=21, CountryType = CountryList.US},
new Person{ Name="Name 3", Age=24, CountryType = CountryList.Israel},
new Person{ Name="Name 4", Age=24, CountryType = CountryList.Israel},
new Person{ Name="Name 5", Age=24, CountryType = CountryList.Russia},
new Person{ Name="Name 6", Age=24, CountryType = CountryList.India},
new Person{ Name="Name 7", Age=24, CountryType = CountryList.Russia},
new Person{ Name="Name 8", Age=24, CountryType = CountryList.Russia},
new Person{ Name="Name 9", Age=24, CountryType = CountryList.Japan},
new Person{ Name="Name 10", Age=24, CountryType = CountryList.Japan},
new Person{ Name="Name 11", Age=24, CountryType = CountryList.India},
new Person{ Name="Name 12", Age=24, CountryType = CountryList.India},
};
PersonViewModelList = myList.GroupBy(x => x.CountryType)
.Select(g => new PersonViewModel()
{
CountryType = g.Key,
Names = g.Select(x => x.Name).OrderBy(n => n).ToList()
});
}
}
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
public CountryList CountryType { get; set; }
}
public class PersonViewModel
{
public CountryList CountryType { get; set; }
public List<string> Names { get; set; }
}
public enum CountryList
{
India,
Russia,
US,
Israel,
Japan
}
UserControl (XAML file)
<TreeView ItemsSource="{Binding PersonViewModelList}">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Path=Names}" DataType="{x:Type local:PersonViewModel}">
<HierarchicalDataTemplate.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=CountryType}"></TextBlock>
</DataTemplate>
</HierarchicalDataTemplate.ItemTemplate>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
Expected:
I am pretty not sure what change I should do in TreeView to make it work. Thanks again.
Your current Person
type is not suited or valid for your requirements. You need to transform your data into an hierarchical view model:
public class PersonViewModel
{
public CountryList CountryType { get; set; }
public List<string> Names { get; set; }
}
Just group your current myList
by CountryType
and bind to the result:
var transformedList = myList
.GroupBy(x => x.CountryType)
.Select(g => new PersonViewModel()
{
CountryType = g.Key,
Names = g.Select(x => x.Name).OrderBy(n => n).ToList()
});
XAML:
<TreeView ItemsSource="{Binding PersonViewModelList}">
<TreeView.Resources>
<HierarchicalDataTemplate ItemsSource="{Binding Names}" DataType="{x:Type local:PersonViewModel}">
<TextBlock Text="{Binding CountryType}" />
</HierarchicalDataTemplate>
</TreeView.Resources>
</TreeView>