wpf combobox default value to textBlock - wpf

I need to add a default value 'select' in the combobox.I cant add this value to the database.This location value is dynamic.It appears based upon the userrole. I tried different ways nothing worked.Please help.
<ComboBox Width="140" ItemsSource="{Binding SecurityContexts, Mode=OneWay}"
SelectedItem="{Binding ActiveSecurityContext, Mode=TwoWay}"
ToolTip="Working Location">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Location}"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
The code behind is
SecurityContexts = new ObservableCollection(_currentUser.ApplicationSecurityContexts);
public interface IApplicationSecurityContext
{
IRole Role { get; }
string Location { get; }
IEnumerable<string> Budgets { get; }
}
public IApplicationSecurityContext ActiveSecurityContext
{
get { return this._currentUser.ActiveSecurityContext; }
set
{
if (this._currentUser.ActiveSecurityContext != value)
{
this._currentUser.ChangeActiveSecurityContext(value);
RaisePropertyChanged("CurrentUser");
LoadData();
}
}
}

You can achieve your goal using CompositeCollection
you can do this. Define resource in your grid/usercontrol/combobox:
<Grid.Resources>
<CollectionViewSource x:Key="cvs" Source="{Binding Binding SecurityContexts, Mode=OneWay}" />
<DataTemplate DataType="{x:Type c:SecurityContexts}">
<TextBlock Text="{Binding Location}"/>
</DataTemplate>
</Grid.Resources>
then your combobox itemsource will be:
<ComboBox.ItemsSource>
<CompositeCollection>
<ComboBoxItem>
<TextBlock Text="select"/>
</ComboBoxItem>
<CollectionContainer Collection="{Binding Source= {StaticResource cvs}}"/>
</CompositeCollection>
</ComboBox.ItemsSource>
It should work. You need to define your datatemplate for your collection in the resource too, to define how your item will be displayed
Note that c in c:SecurityContexts is the path where you defined your custom object

Related

How can i add different images to combobox itemssource array

I would like to add different images next to each item in a combobox itemssource. Here's what i have at the moment.
<ComboBox x:Name="cmb" HorizontalAlignment="Left" Width="135" Height="22"
SelectedItem="{Binding myViewMode}" Margin="5,0,0,0">
<ComboBox.ItemsSource>
<x:Array Type="sys:String" xmlns:sys="clr-namespace:System;assembly=mscorlib">
<sys:String>Oranges</sys:String>
<sys:String>Mangoes</sys:String>
</x:Array>
</ComboBox.ItemsSource>
</ComboBox>
How should add the two diffent images using an itemtemplate. Thanks
Edit One
This is what i have tried with itemtemplate
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Source="{Binding OrangesImage}" Height="100"/>
<Image Source="{Binding MangoesImage}" />
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
It's here that am really stuck.
At the moment your item template contains only two images, so you will show two images and no text for each item!
I would suggest you change your ItemsSource to code behind so you can have text and image properties.
First make a simple Fruit class:
public class Fruit
{
public string FruitName { get; set; }
public string FruitImage { get; set; }
}
Then create a list of these fruits and set the ItemsSource of your combo box to this list:
var fruits = new List<Fruit>();
fruits.Add(new Fruit() { FruitName = "Mangos", FruitImage = #"C:\mangoimage.jpg" });
fruits.Add(new Fruit() { FruitName = "Oranges", FruitImage = #"C:\mangoimage.jpg" });
cmb.ItemsSource = fruits;
Then simplify your XAML thus:
<ComboBox x:Name="cmb" HorizontalAlignment="Left" Width="135" Height="22" SelectedItem="{Binding myViewMode}" Margin="5,0,0,0">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding FruitName}"/>
<Image Source="{Binding FruitImage}" Height="100"/>
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
In your ItemSource your image should consists as Uri path with BitMapImage Class then only Images are accepted in ItemTemplate in ComboBox
Xaml Code
<ComboBox x:Name="cmb" HorizontalAlignment="Left" Width="135" Height="22"
SelectedItem="{Binding myViewMode}" Margin="5,0,0,0">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Width="25" Height="25" Source="{Binding FruitName}"/>
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
Your Model Class
public class Fruit
{
public string FruitName { get; set; }
}
Your ItemSource should Consists as:
fruitCollection.Add(new Fruit() {FruitName= new BitmapImage(new Uri("C:\mangoimage.jpg", UriKind.Relative))});

Combobox with static and dynamic data together in wpf

As the title suggests I want to add a static Item to a dataBound ComboBox.
I have refered this post.
Databinding a Combobox :
<ComboBox Name="comboBox1" Width="Auto" ItemsSource="{Binding}" />
Adding Static Items to a combobox :
<ComboBox Text="Is not open">
<ComboBoxItem Name="cbi1">Item1</ComboBoxItem>
<ComboBoxItem Name="cbi2">Item2</ComboBoxItem>
<ComboBoxItem Name="cbi3">Item3</ComboBoxItem>
</ComboBox>
Doing the above things together using CompositeCollection :
<ComboBox>
<ComboBox.Items>
<CompositeCollection>
<CollectionContainer Collection="{Binding Source={...whatever...}" />
<ComboBoxItem Name="cbi1">Item1</ComboBoxItem>
<ComboBoxItem Name="cbi2">Item2</ComboBoxItem>
<ComboBoxItem Name="cbi3">Item3</ComboBoxItem>
</CompositeCollection>
</ComboBox.Items>
</ComboBox>
But the above examples does not solve my problem.
I want to add a static Item to a dataBound ComboBox in which I use DataTemplate
Here is my Code for dataBound ComboBox (I don't know how to add static Items):
<ComboBox x:Name="cbUnder" ItemsSource="{Binding GroupsAndCorrespondingEffects}"
IsEditable="True" SelectedItem="{Binding SelectedGroup, Mode=TwoWay}"
TextSearch.TextPath="GroupName" Grid.Column="1" Grid.ColumnSpan="4" Grid.Row="3">
<ComboBox.ItemTemplate>
<DataTemplate>
<VirtualizingStackPanel Orientation="Horizontal">
<TextBlock Text="{Binding GroupName}" Width="250"/>
<TextBlock Text="{Binding CorrespondingEffect}" />
</VirtualizingStackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
Update as requested by aks81 :
Here is the code for GroupsAndCorrespondingEffects
public GroupsViewModel()
{
using (DBEntities db = new DBEntities())
{
GroupsAndCorrespondingEffects = (from g in db.Groups
select new GroupAndCorrespondingEffect
{
GroupName = g.Name,
CorrespondingEffect = g.Type_Effect.Name
}
).ToList().OrderBy(g => g.GroupName);
Items = (from e in db.Type_Effect
select e.Name).ToList();
}
}
public static GroupsViewModel CurrentInstance { get { return Instance; } }
private IEnumerable<GroupAndCorrespondingEffect> _groupsAndCorrespondingEffects;
public IEnumerable<GroupAndCorrespondingEffect> GroupsAndCorrespondingEffects
{
get
{
return _groupsAndCorrespondingEffects;
}
set
{
_groupsAndCorrespondingEffects = value;
OnPropertyChanged("GroupsAndCorrespondingEffects");
}
}
Check out this link and let me know if it was useful :)
http://social.msdn.microsoft.com/Forums/vstudio/en-US/86229c53-15bd-4780-bee3-c6c2cdae81e7/select-multiple-checkboxes-placed-inside-a-combobox
have a nice day!

One combo box filtering another combo box in a WPF Datagrid

I have a datagrid which has two combo box columns in it. The first combo box is a list of PersonnelTypes. Depending on which PersonnelType is selected, the second combo box should fill up with a list of Resources that match the selected PersonnelType
The problem is, lets say I have two rows of data, if I change the PersonnelType of one row, the datagrid will set the itemsource for all of the Resources in every row. I only want it to filter the row that I am in, not all the rows.
Here's the xaml for the part of the datagrid that has the combo boxes:
<DataGridTemplateColumn Header="Personnel Type" Width="Auto">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Grid>
<ComboBox Name="cmbPersonnelTypes" FontWeight="Bold" ItemsSource="{Binding ViewModel.PersonnelTypes, RelativeSource={RelativeSource AncestorType=Window}}" SelectedItem="{Binding PersonnelType, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" SelectedValuePath="ID" DisplayMemberPath="Description" SelectionChanged="cmbPersonnelTypes_SelectionChanged" />
</Grid>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="Name" Width="Auto">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Grid>
<ComboBox Name="cmbPersonnelName" FontWeight="Bold" ItemsSource="{Binding ViewModel.ResourcesToChooseFrom, RelativeSource={RelativeSource AncestorType=Window},UpdateSourceTrigger=PropertyChanged}" SelectedItem="{Binding Resource, Mode=TwoWay}" SelectedValuePath="Refno" DisplayMemberPath="Name" />
</Grid>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
Here is the xaml for the whole data grid (just in case you need to see it):
<DataGrid AutoGenerateColumns="False" CanUserSortColumns="False" CanUserDeleteRows="True" IsReadOnly="True" Background="LightGray" CanUserAddRows="False" Margin="5" SelectedItem="{Binding SelectedLA_JobPersonnel}" ItemsSource="{Binding LA_Personnel}" Grid.ColumnSpan="4" MouseDoubleClick="DataGrid_MouseDoubleClick_1">
<DataGrid.Resources>
<ViewModels:BindingProxy x:Key="proxy" Data="{Binding}" />
</DataGrid.Resources>
<DataGrid.Columns>
<DataGridTemplateColumn Header="Personnel Type" Width="Auto">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Grid>
<ComboBox Name="cmbPersonnelTypes" FontWeight="Bold" ItemsSource="{Binding ViewModel.PersonnelTypes, RelativeSource={RelativeSource AncestorType=Window}}" SelectedItem="{Binding PersonnelType, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" SelectedValuePath="ID" DisplayMemberPath="Description" SelectionChanged="cmbPersonnelTypes_SelectionChanged" />
</Grid>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="Name" Width="Auto">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Grid>
<ComboBox Name="cmbPersonnelName" FontWeight="Bold" ItemsSource="{Binding ViewModel.ResourcesToChooseFrom, RelativeSource={RelativeSource AncestorType=Window},UpdateSourceTrigger=PropertyChanged}" SelectedItem="{Binding Resource, Mode=TwoWay}" SelectedValuePath="Refno" DisplayMemberPath="Name" />
</Grid>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn> <DataGridTemplateColumn Header="Date Out" Width="20*" >
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Background="LightGray" FontWeight="Bold" Text="{Binding DateOut, Mode=TwoWay, Converter={StaticResource thisNullDateConverter}, StringFormat={}{0:MMM-dd-yyyy hh:ss tt}}">
</TextBlock>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<Toolkit:DateTimePicker Background="LightGray" FontWeight="Bold" Value="{Binding Path=DateOut, Mode=TwoWay, Converter={StaticResource thisNullDateConverter}}" Format="Custom" FormatString="MMM dd yyyy hh:ss tt"></Toolkit:DateTimePicker>
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="Date In" Width="20*">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Background="LightGray" FontWeight="Bold" Text="{Binding DateIn, Mode=TwoWay, Converter={StaticResource thisNullDateConverter}, StringFormat={}{0:MMM-dd-yyyy hh:ss tt}}">
</TextBlock>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<Toolkit:DateTimePicker Background="LightGray" FontWeight="Bold" Value="{Binding Path=DateIn, Mode=TwoWay, Converter={StaticResource thisNullDateConverter}}" Format="Custom" FormatString="MMM dd yyyy hh:ss tt"></Toolkit:DateTimePicker>
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
Here is the code behind for the xaml (xaml.cs):
public JobEditorViewModel ViewModel
{
get { return viewModel; }
}
private void cmbPersonnelTypes_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var combobox = sender as ComboBox;
if (combobox != null)
{
var selectedPersonnelType = combobox.SelectedItem as PersonnelType;
viewModel.SetResourcesToChooseFrom(selectedPersonnelType);
}
}
Here is the code in the viewModel:
public BindingList<PersonnelType> PersonnelTypes
{
get; set;
}
public JobEditorViewModel(int jobid, string region, DataAccessDataContext db, ServiceUserControlViewModel serviceViewModel)
{
PersonnelTypes = new BindingList<PersonnelType>(_db.PersonnelTypes.OrderBy(p => p.Head).ThenBy(p => p.Description).ToList());
}
private BindingList<Resource> _resourcesToChooseFrom;
public BindingList<Resource> ResourcesToChooseFrom
{
get { return _resourcesToChooseFrom; }
set
{
_resourcesToChooseFrom = value;
NotifyPropertyChanged("ResourcesToChooseFrom");
}
}
public void SetResourcesToChooseFrom(PersonnelType personnelType)
{
ResourcesToChooseFrom =
new BindingList<Resource>(_db.Resources.Where(r => r.Head == personnelType.Head && r.Refno > 2).OrderBy(r=>r.Name).ToList());
}
If you need to see more, let me know
Well, with some help from a colleague here at work, we figured out what I needed to do. Multibinding is the answer. First off we kind of hacked around so that the two combo boxes could be in the same column by placing them both in a grid and placing the grid in the one column. So now both combo boxes can see each other because they are in the same DataGridTemplateColumn. Before, we couldn't get them to see each other because they lost scope of each other in being two separate DataGridTemplateColumns.
Here's what we did in the xaml:
<DataGridTemplateColumn Header="Personnel Type-Name" Width="Auto" >
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Grid >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="170"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Border Grid.Column="0" BorderBrush="Black" BorderThickness="1">
<TextBlock Text="{Binding PersonnelType.Description}"/>
</Border>
<Border Grid.Column="1" BorderBrush="Black" BorderThickness="1">
<TextBlock Text="{Binding Resource.Name}"/>
</Border>
</Grid>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<Grid >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="170"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<ComboBox Name="cmbPersonnelTypes" Grid.Column="0" FontWeight="Bold" ItemsSource="{Binding ViewModel.PersonnelTypes, RelativeSource={RelativeSource AncestorType=Window}, UpdateSourceTrigger=PropertyChanged}" SelectedItem="{Binding PersonnelType, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" SelectedValuePath="ID" DisplayMemberPath="Description" />
<ComboBox Name="cmbPersonnelName" Grid.Column="1" FontWeight="Bold" SelectedItem="{Binding Resource, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" SelectedValuePath="Refno" DisplayMemberPath="Name" >
<ComboBox.ItemsSource>
<MultiBinding Converter="{StaticResource FilteredPersonnelConverter}">
<Binding Path="ViewModel.AvailablePersonnel" RelativeSource="{RelativeSource AncestorType=Window}"/>
<Binding Path="SelectedItem" ElementName="cmbPersonnelTypes"/>
<Binding Path="ViewModel.SelectedGlobalResourceViewOption" RelativeSource="{RelativeSource AncestorType=Window}"/>
</MultiBinding>
</ComboBox.ItemsSource>
</ComboBox>
</Grid>
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
You'll notice there is a ValueConverter in the MultiBinding called FilteredPersonnelConverter. This value converter does all the filtering for me. Here's the code for that:
public class FilteredPersonnelListValueConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
var allResources = values[0] as IList<Resource>;
var personnelType = values[1] as PersonnelType;
var selectedGlobalResourceView = values[2] as ResourceViewOption;
if (personnelType == null)
return allResources;
if(selectedGlobalResourceView.ResourceViewTitle=="Regional")
return allResources.Where(r => r.Head == personnelType.Head && r.Obsolete == false && r.Location.Region.RegionID.Trim()==SettingsManager.OpsMgrSettings.Region.Trim()).OrderBy(r => r.Name).ToList();
if (selectedGlobalResourceView.ResourceViewTitle == "Local")
return allResources.Where(r => r.Head == personnelType.Head && r.Obsolete == false && r.LocnID.Trim() == SettingsManager.OpsMgrSettings.LOCNCODE.Trim()).OrderBy(r => r.Name).ToList();
return allResources.Where(r => r.Head == personnelType.Head &&r.Obsolete==false).OrderBy(r => r.Name).ToList();
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
So if anyone else is doing something like this, look into Multibinding, it will change your life
When the user changes the PersonelType dropdown in the view, the ViewModel should then filter the list of Resources (which should update the second dropdown box with the correct information).
Really your view model just needs to be set up to respond to changes on the view. That's what it boils down to.
Looking here:
public JobEditorViewModel(int jobid, string region, DataAccessDataContext db, ServiceUserControlViewModel serviceViewModel)
{
PersonnelTypes = new BindingList<PersonnelType>(_db.PersonnelTypes.OrderBy(p => p.Head).ThenBy(p => p.Description).ToList());
}
it looks like you set the personel types in the constructor, but you aren't responding to user changes. You need to do that in the PersonelType Binding in your view model.
EDIT
I see now that you're handling the selection changed. But really I think this should be done in the view model itself. Specifically because you actually access the viewmodel from the view to do make your changes.
Example
So here's my VM:
class ViewModel : INotifyPropertyChanged
{
DispatcherTimer timer = new DispatcherTimer();
public ViewModel()
{
// Create my observable collection
this.DateTimes = new ObservableCollection<DateTime>();
// Every second add anothe ritem
timer.Interval = TimeSpan.FromSeconds(1);
timer.Tick += new EventHandler(timer_Tick);
timer.Start();
}
void timer_Tick(object sender, EventArgs e)
{
// This adds to the collection
this.DateTimes.Add(DateTime.Now);
}
public ObservableCollection<DateTime> DateTimes { get; private set; }
public event PropertyChangedEventHandler PropertyChanged;
}
and My View:
<ListBox ItemsSource="{Binding DateTimes}"/>
Notice that I don't rebuild the collection. I just set it once, and then change it's size as neccesary.

How to bind two ObservableCollection(s) to one ListBox?

Does anybody know how to binding two ObservableCollections in one ListBox?
these two ObservableCollections both have a Property string "name" to display in the ListBox,
int the ListBox top area, will display the ObservableCollection1 items and in the ListBox bottom area I want display the ObservableCollection2 items, how to do that?
<ListBox x:Name="m_CtrlMediaList" Grid.Column="2" AllowDrop="True" SelectionMode="Extended">
<ListBox.ItemsSource>
<CompositeCollection>
<CollectionContainer Collection="{Binding directorys}"/>
<CollectionContainer Collection="{Binding files}"/>
</CompositeCollection>
</ListBox.ItemsSource>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical">
<TextBlock Text="{Binding name, Mode=OneWay}" FontWeight="Bold" FontSize="14"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
the data is like:
class ElementFile
{
...
string name (get;set;}
...
}
class ElementDirectory
{
...
string name (get;set;}
...
public ObservableCollection<ElementDirectory> directorys { get; set; }
public ObservableCollection<ElementFile> files { get; set; }
...
}
Why can not display the "name"?
The composite collection is what you are looking for. Example.

WPF Treeview - Binding to a collection with different depths, and styling differently

Apologies for the long post -- Read a few threads about this, but still find it hard to implement. Basically, I have a collection of objects, defined as:
public class LibData
{
public string Name { get; set; }
ObservableCollection<LibObject> _list;
public ObservableCollection<LibObject> List { get { return _list; } }
public LibData(string name, LibDataType type)
{
this.Name = name;
_list = new ObservableCollection<LibObject>();
}
}
and the object:
public class LibObject
{
public string Name { get; set; }
public LibObject(string name)
{
this.Name = name;
}
}
My main problem is in the XAML, and styling this TreeView. I need to have a specific style for a "root" item, and a specific style for a "leaf". Thing is, that one item in the bound list is "Root->Leaf", and another is "Root->Child->Leaf".
I tried this:
<TreeView x:Name="myTree" ItemsSource="{x:Static local:myDataList}">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Path=List}" >
<Grid>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=Name}" />
<CheckBox IsChecked="True" Content="HeaderCheckbox"/>
</StackPanel>
</Grid>
<HierarchicalDataTemplate.ItemTemplate >
<DataTemplate>
<Grid>
<StackPanel Orientation="Horizontal">
<CheckBox IsChecked="True" Content="LeafCheckbox" />
<TextBlock Text="{Binding Path=Name}"/>
</StackPanel>
</Grid>
</DataTemplate>
</HierarchicalDataTemplate.ItemTemplate>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
This obviously works fine for the "Root->Leaf" item, but not for the "Root-Child-Leaf".
The XAML implementation seems to be more of a "hard coded" solution, where I know that the item layout is always "Root->Leaf" - how do I make this dynamic?
Again, I have seen solutions to different levels (including using converters), but the problem i'm having is that I need specific styles to root and leaf and nothing for levels in between.
I'm wondering if I'm looking at this completely wrong ...
Easy way to do this. Pull the DataTemplates out of the TreeView and put them in the resources section. Specify the DataType property for each DataTemplate, but do not include a key. The ItemTemplateSelector (a property of type DataTemplateSelector) on the TreeView will do the magic of using whichever DataTemplate suits the correct item type.
Create a HierarchicalDataTemplate for types Root and Child, and a DataTemplate for type Leaf.
Something like this:
<Window.Resources>
<ResourceDictionary>
<DataTemplate DataType="{x:Type local:Leaf}">
<Grid>
<StackPanel Orientation="Horizontal">
<CheckBox IsChecked="True" Content="LeafCheckbox" />
<TextBlock Text="{Binding Path=SomeValue}"/>
</StackPanel>
</Grid>
</DataTemplate>
<HierarchicalDataTemplate DataType="{x:Type local:Child}"
ItemsSource="{Binding Children}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="Child " />
<TextBlock Text="{Binding Path=SomeValue}" />
</StackPanel>
</HierarchicalDataTemplate>
<HierarchicalDataTemplate DataType="{x:Type local:Root}"
ItemsSource="{Binding Children}">
<Grid>
<StackPanel Orientation="Horizontal">
<TextBlock Text="Root " />
<TextBlock Text="{Binding Path=SomeValue}" />
</StackPanel>
</Grid>
</HierarchicalDataTemplate>
</ResourceDictionary>
</Window.Resources>
<Grid>
<TreeView x:Name="myTree" ItemsSource="{Binding}" />
</Grid>

Resources