I have a fairly simple data model:
public class ServiceModel
{
private static readonly IQmiServiceManager ServiceManager = Bootstrap.Instance.DomainManager.QmiServiceManager;
private string _serviceName;
private ObservableCollection<string> _serviceMessages;
public string Name
{
get { return _serviceName; }
private set { _serviceName = value.ToUpper(); }
}
public ObservableCollection<string> Messages
{
get { return _serviceMessages; }
private set { _serviceMessages = value; }
}
public ServiceModel(string ServiceName, IList<string> ServiceMessages)
{
Name = ServiceName;
Messages = new ObservableCollection<string>(ServiceMessages);
}
}
...which is encapsulated in this view model:
public class ServiceCollectionViewModel
{
private readonly ObservableCollection<ServiceModel> _serviceModels = new ObservableCollection<ServiceModel>();
public ObservableCollection<ServiceModel> ServiceModels
{
get { return _serviceModels; }
}
}
I have the following treeview xaml definition:
<TreeView Name="ServiceTree" Grid.Row="1" ItemsSource="{Binding Services}">
<TreeView.ItemContainerStyle>
<Style TargetType="{x:Type TreeViewItem}">
<Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}" />
<Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" />
<Setter Property="FontWeight" Value="Normal" />
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="FontWeight" Value="Bold" />
</Trigger>
</Style.Triggers>
</Style>
</TreeView.ItemContainerStyle>
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding}">
<TextBlock Text="{Binding Name}"/>
<HierarchicalDataTemplate.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Messages}"/>
</DataTemplate>
</HierarchicalDataTemplate.ItemTemplate>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
Nothing is being output in the tree. I have tried following several tutorials on hierarchical data-binding but I'm simply having difficulty understanding the proper technique for my specific situation.
Also, how should the data-context be set? I am setting the context as follows within the code-behind of the view:
public partial class ServiceView : UserControl
{
private readonly ServiceCollectionViewModel _serviceCollection = new ServiceCollectionViewModel();
public ObservableCollection<ServiceModel> Services
{
get { return _serviceCollection.ServiceModels; }
}
public ServiceView()
{
InitializeComponent();
DataContext = _serviceCollection;
_serviceCollection.LoadServices();
}
}
You seem to be very confused. You're trying to data bind to your
ServiceView.Services
property, so what is theServiceCollectionViewModel
class for? The sole purpose of a view model is to provide all of the data (and functionality) required for its view.Now we can go different routes... it all depends what you actually want. If you want to data bind from outside the
UserControl
to theServiceView.Services
property, then you must declare theServices
property as aDependencyProperty
. Inside yourUserControl
, you would then data bind to the property using aRelativeSource Binding
like this:Outside:
Inside:
With this method, there is no need to set the
DataContext
to anything as we are usingRelativeSource
to set the data source. Alternatively, you could set theDataContext
to either the internalUserControl
code behind, or an instance of a view model (from either inside or outside) and then normally data bind like this:So, to recap, if you set the
DataContext
to an instance of an object, then yourBinding Path
s look at the properties in that object to resolve themselves. Otherwise, if you set aRelativeSource
(orElementName
) in yourBinding Path
, then you are changing the data source for thatBinding
only and yourBinding Path
s should be properties from those objects instead.UPDATE >>>
The
HierarchicalDataTemplate
Class is basically a slight extension on the regular oldDataTemplate
class and can be thought of aDataTemplate
with anItemsSource
property. Therefore, if you can define the content of aDataTemplate
, then you can define the content of aHierarchicalDataTemplate
... just make sure to set theHierarchicalDataTemplate.ItemsSource
property to a valid collection property... in your case, theMessages
property:If you're not too clear on
DataTemplate
, take a look at the Data Binding Overview page on MSDN.