Reputation: 7414
I am trying to bind a collection of objects held by a Model to a treeview in WPF. My XML to do this was based on WPF Treeview Databinding Hierarchal Data with mixed types but I am not having any luck.
My current XAML looks like this for the treeview.
<TreeView Name="ConfigurationFilter">
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type models:MyModel}" ItemsSource="{Binding Path=Filters.FilterType1}">
<StackPanel Orientation="Horizontal">
<CheckBox></CheckBox>
<Label Content="{Binding Path=Name}"></Label>
</StackPanel>
</HierarchicalDataTemplate>
</TreeView.Resources>
</TreeView>
I have a model that looks like this
public class MyModel
{
public Observable<MyFilter> FilterType1 {get;set;}
public Observable<MyFilter> FilterType2 {get;set;}
}
public class MyFilter
{
public string Name {get;set;}
public bool IsSelected {get;set;}
}
Within my MainWindow.Xaml.cs I have the following:
public partial class MainWindow : Window
{
public MyModel Filters { get; set; }
}
The FilterType1 property has 331 items in it. Yet when I run the app, the binding never happens. I do not see any items in my Treeview. What am I doing wrong?
Update 1
I have added my main window as the data context for the treeview and the binding as suggested but i still do not have any items in the tree
<TreeView Name="ConfigurationFilter" ItemsSource="{Binding Filters}">
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type models:MyModel}" ItemsSource="{Binding Path=Filters.FilterType1}">
<StackPanel Orientation="Horizontal">
<CheckBox></CheckBox>
<Label Content="{Binding Path=Name}"></Label>
</StackPanel>
</HierarchicalDataTemplate>
</TreeView.Resources>
</TreeView>
and my MainWindow.cs
public MainWindow()
{
InitializeComponent();
ConfigurationFilter.DataContext = this;
}
Upvotes: 3
Views: 3840
Reputation: 7414
I was able to get this working by modifying my treeview to bind to a composite view model as demonstrated on CodeProject.
<TreeView Grid.ColumnSpan="2" Grid.RowSpan="2">
<TreeViewItem Header="Routes" Name="RouteView" ItemsSource="{Binding Routes}">
<TreeViewItem.ItemTemplate>
<HierarchicalDataTemplate DataType="{x:Type viewModels:RouteViewModel}" ItemsSource="{Binding}">
<StackPanel Orientation="Horizontal">
<Label Content="{Binding Path=Name}" VerticalAlignment="Center"></Label>
</StackPanel>
</HierarchicalDataTemplate>
</TreeViewItem.ItemTemplate>
</TreeViewItem>
</TreeView>
Since my treeview will have multiple root nodes that are pre-determined, I had to bind the datasource to each root TreeViewItem
. Then I placed my objects into a composite viewmodel.
Composite View Model
public class DomainViewModel
{
public ReadOnlyCollection<RouteViewModel> Routes { get; set; }
public ReadOnlyCollection<SkyViewModel> SkyLines { get; set; }
public DomainViewModel(List<Route> routes)
{
Routes = new ReadOnlyCollection<RouteViewModel>(
(from route in routes
select new RouteViewModel(route))
.ToList<RouteViewModel>());
}
Skylines = new ReadOnlyCollection<SkyViewModel>(
(from route in routes
select new SkyViewModel(route))
.ToList<SkyViewModel>());
}
}
ViewModel - Only 1 shown to help readability.
public class RouteViewModel : INotifyPropertyChanged
{
private Route _route; // My actual database model.
public string Name
{
get { return _route.RouteName; }
}
public RouteViewModel(Route route)
{
_route = route;
}
}
MainWindow
public MainWindow()
{
InitializeComponent();
this.DomainFilterTreeView.DataContext = new this.Domains;
}
Upvotes: 3
Reputation: 10865
TreeView
doesn't have an ItemsSource
bound to. Assuming the DataContext
of the TreeView
is your MainWindow
, then you can add the ItemsSource
binding.
<TreeView Name="ConfigurationFilter" ItemsSource={Binding Filters}>
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type models:MyModel}" ItemsSource="{Binding Path=Filters.FilterType1}">
<StackPanel Orientation="Horizontal">
<CheckBox></CheckBox>
<Label Content="{Binding Path=Name}"></Label>
</StackPanel>
</HierarchicalDataTemplate>
</TreeView.Resources>
</TreeView>
MainWindow.xaml.cs
public partial class MainWindow : Window
{
public MainWindow()
{
ConfigurationFilter.DataContext = this;
}
public MyModel Filters { get; set; }
}
Upvotes: 0