I have the following markup (xaml):
<ListBox Name="lbEurInsuredType" HorizontalContentAlignment="Stretch">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid Margin="0,2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"></ColumnDefinition>
<ColumnDefinition Width="30"></ColumnDefinition><ColumnDefinition Width="2"></ColumnDefinition>
<ColumnDefinition Width="30"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Title}"></TextBlock>
<TextBox Text="{Binding Uw}" Grid.Column="1"></TextBox>
<TextBox Text="{Binding Partner}" Grid.Column="3"></TextBox>
</Grid>
</DataTemplate></ListBox.ItemTemplate>
</ListBox>
This all looks ok, but now above column 1 and 3 I want to place a header. Can anyone show me how I add headers to my two columns.
Listview is surely the best option, but, if you need to use a listbox you could modify the template of the listbox in this way.
<ListBox Name="lbEurInsuredType" HorizontalContentAlignment="Stretch">
<ListBox.Template>
<ControlTemplate>
<DockPanel LastChildFill="True">
<Grid DockPanel.Dock="Top" Height="30">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"></ColumnDefinition>
<ColumnDefinition Width="30"></ColumnDefinition>
<ColumnDefinition Width="2"></ColumnDefinition>
<ColumnDefinition Width="30"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Label Grid.Column="0">Column 1</Label>
<Label Grid.Column="1">Column 2</Label>
<Label Grid.Column="2">Column 3</Label>
<Label Grid.Column="3">Column 4</Label>
</Grid>
<ItemsPresenter></ItemsPresenter>
</DockPanel>
</ControlTemplate>
</ListBox.Template>
<ListBox.ItemTemplate>
<DataTemplate>
<Grid Margin="0,2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"></ColumnDefinition>
<ColumnDefinition Width="30"></ColumnDefinition>
<ColumnDefinition Width="2"></ColumnDefinition>
<ColumnDefinition Width="30"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Title}"></TextBlock>
<TextBox Text="{Binding Uw}" Grid.Column="1"></TextBox>
<TextBox Text="{Binding Partner}" Grid.Column="3"></TextBox>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
I recommend that you use a ListView
instead which more appropriate to you case, you could use a GridView
inside and define the columns that you need then restyle them much more easily
<ListView Name="lbEurInsuredType" HorizontalContentAlignment="Stretch" ItemsSource="{Binding Items}">
<ListView.View>
<GridView>
<GridView.Columns>
<GridViewColumn>
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Title}"></TextBlock>
</DataTemplate>
</GridViewColumn.CellTemplate>
<GridViewColumn.Header>
<TextBlock Text="Column 1"></TextBlock>
</GridViewColumn.Header>
</GridViewColumn>
<GridViewColumn>
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Uw}"></TextBlock>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn>
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Partner}"></TextBlock>
</DataTemplate>
</GridViewColumn.CellTemplate>
<GridViewColumn.Header>
<TextBlock Text="Column 3"></TextBlock>
</GridViewColumn.Header>
</GridViewColumn>
</GridView.Columns>
</GridView>
</ListView.View>
</ListView>
I haven't run this so there might be some issue with the code but this will give you the idea to add headers to the ListBox
<ListBox Name="lbEurInsuredType" HorizontalContentAlignment="Stretch">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid Margin="0,2">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"></ColumnDefinition>
<ColumnDefinition Width="30"></ColumnDefinition>
<ColumnDefinition Width="2"></ColumnDefinition>
<ColumnDefinition Width="30"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock Text="Title" ></TextBlock>
<TextBlock Text="Uw" Grid.Column="1" ></TextBox>
<TextBlock Text="Partner" Grid.Column="3" ></TextBox>
<TextBlock Text="{Binding Title}" Grid.Row="1"></TextBlock>
<TextBox Text="{Binding Uw}" Grid.Column="1" Grid.Row="1"></TextBox>
<TextBox Text="{Binding Partner}" Grid.Column="3" Grid.Row="1"></TextBox>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Even Listbox can be inside a user control with dynamic data template
<Grid Style="{StaticResource TableHeader}">
<Grid.Resources>
<Style TargetType="{x:Type Border}" BasedOn="{StaticResource TableBorder}"/>
<Style TargetType="{x:Type TextBlock}" BasedOn="{StaticResource TextTableHeader}">
<Setter Property="TextWrapping" Value="Wrap"/>
</Style>
</Grid.Resources>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Border BorderThickness="1">
<TextBlock Text="Card"/>
</Border>
<Border Grid.Column="1" BorderThickness="0 1 1 1">
<TextBlock Text="Type"/>
</Border>
<Border Grid.Column="2" BorderThickness="0 1 1 1">
<TextBlock Text="Limit"/>
</Border>
<Border Grid.Column="3" BorderThickness="0 1 1 1">
<TextBlock Text="Amount"/>
</Border>
<Border Grid.Column="4" BorderThickness="0 1 1 1">
<TextBlock Text="Payment Due"/>
</Border>
</Grid>
<ListBox Style="{StaticResource ListBoxStyle}"
ItemsSource="{Binding Source}"
SelectedItem="{Binding SelectedItem}"
IsHitTestVisible="{Binding IsSelectionActive}"
ItemTemplate="{Binding ItemTemplate}" />
</Grid>
ListBox has no HeaderTemplate
. ListView
is not the best option because it does not support Width="*"
. If you get desperate and go to DataGrid
you might be getting a lot more than you need. The solution is to use a HeaderedItemsControl
Just change the name of the Collection you are binding to and change the binding properties.
<!-- actual XAML -->
<HeaderedItemsControl
ItemTemplate="{DynamicResource CorrugationItemTemplate}"
ItemsSource="{Binding CorrugationItemCollection}"
Style="{DynamicResource CorrugationStyle}"/>
<!-- this goes in the resource dict -->
<DataTemplate x:Key="CorrugationItemTemplate">
<Grid Width="Auto" Background="#e1e1e1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="60"/>
<ColumnDefinition Width="60"/>
<ColumnDefinition Width="60"/>
<ColumnDefinition Width="60"/>
</Grid.ColumnDefinitions>
<Border Grid.Column="0" Background="Lime" >
<Label Content="{Binding RangeLabel}" />
</Border>
<Border Grid.Column="1" Background="Orange" >
<Label Content="{Binding LeftPreGrind}" />
</Border>
<Border Grid.Column="2" Background="Lime" >
<Label Content="{Binding RightPreGrind}" />
</Border>
<Border Grid.Column="3" Background="Orange" >
<Label Content="{Binding LeftPostGrind}" />
</Border>
<Border Grid.Column="4" Background="Lime" >
<Label Content="{Binding RightPostGrind}" />
</Border>
</Grid>
</DataTemplate>
<Style TargetType="{x:Type HeaderedItemsControl}" x:Key="CorrugationStyle">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type HeaderedItemsControl}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="60"/>
<ColumnDefinition Width="60"/>
<ColumnDefinition Width="60"/>
<ColumnDefinition Width="60"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="20pt"/>
<RowDefinition Height="4*"/>
</Grid.RowDefinitions>
<Border Grid.Column="0" Background="Orange" >
<Label Content="Range" />
</Border>
<Border Grid.Column="1" Background="Lime" >
<Label Content="LeftPreGrind" />
</Border>
<Border Grid.Column="2" Background="Orange" >
<Label Content="RightPreGrind" />
</Border>
<Border Grid.Column="3" Background="Lime" >
<Label Content="LeftPostGrind" />
</Border>
<Border Grid.Column="4" Background="Orange" >
<Label Content="RightPostGrind" />
</Border>
<Grid Grid.Row="1" Grid.ColumnSpan="5" Width="Auto" Height="Auto" Background="White">
<ItemsPresenter/>
</Grid>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
You could nest a label (or a text block for that matter) inside one of the column definitions and style it accordingly.
<ColumnDefinition>
<Label Content="Header 1" FontSize="20"/>
</ColumnDefinition>