views:

12

answers:

2

Hi

I think I have a pretty simple goal but cant seem to reach it.

All I want to achieve is to have a ItemsControl (because I don't want the selection functionality of a list) with a header. Preferably a static header.

Currently I'm using a grid for the header and then copying that grid into the ItemTemplate (DataTemple) of the ItemsControl and then placing them one above the other in a grid. It kinda works but its it doesn't always line up nicely etc.

I then found the HeaderedItemsControl which I thought was a brilliant idea but cant get it to work, it just doesn't show the header at all. I have tried the following;

  • Just entering text into the "Header" of the Xaml
  • Placing a grid with TextBlocks with static text within the ItemsControl.Header tag
  • Placing the grid within the HeaderTemplate (Datatemplate) and binding it to a simple object

I'm doing this all in Blend in a small project before moving it into the production app and I'm just using a simple sample data source which I created.

I might be missing the boat completely here but any help would be appreciated.

My current code is as follows, first is my HeaderedItemsControl

<HeaderedItemsControl Header="HeaderedItemsControl"  
        ItemsSource="{Binding Collection, Mode=Default}" 
        ItemTemplate="{DynamicResource ItemsControlDataTemplate}" 
        HeaderTemplate="{DynamicResource ItemsControlHeaderDataTemplate}"/>

then I've got a ItemTemple which works as expected

<DataTemplate x:Key="ItemsControlDataTemplate">
        <Grid d:DesignWidth="268">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="0.754*"/>
                <ColumnDefinition Width="0.246*"/>
            </Grid.ColumnDefinitions>
            <TextBlock Text="{Binding Property1, Mode=Default}" TextWrapping="Wrap" d:LayoutOverrides="Height" HorizontalAlignment="Stretch" Margin="0" />
            <TextBlock Text="{Binding Property2, Mode=Default}" TextWrapping="Wrap" d:LayoutOverrides="Height" Grid.Column="1" HorizontalAlignment="Left" Margin="0" />
        </Grid>
    </DataTemplate>

and then the header which is defiantly opposing its work ethic, I've tried it with binding and with just plain text in the TextBlock.Text property

<DataTemplate x:Key="ItemsControlHeaderDataTemplate">
        <Grid d:DesignWidth="268">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="0.754*"/>
                <ColumnDefinition Width="0.246*"/>
            </Grid.ColumnDefinitions>
            <TextBlock Text="{Binding Header.Header1, Mode=Default, Source={StaticResource SampleDataSource6}}" TextWrapping="Wrap" HorizontalAlignment="Stretch" Margin="0"/>
            <TextBlock Text="{Binding Header.Header2, Mode=Default, Source={StaticResource SampleDataSource6}}" TextWrapping="Wrap" d:LayoutOverrides="Height" Grid.Column="1" HorizontalAlignment="Left" Margin="0"/>
        </Grid>
    </DataTemplate>
A: 

Came across something similar yesterday - for the HeaderedContentControl, try setting the and not the property.

I found it impossible to get bindings working via the - the content was binding correctly. I'd be very interested if someone explains the reasoning.

Hope my workaround above helps.

Chris

cristobalito
A: 

HeaderedItemsControl doesn't have a default style, so it's just using the template from the base ItemsControl class, which does not render any Header. It is only used by the framework as the base class for MenuItem, ToolBar, and TreeViewItem, which define their own templates. You could create your own template that includes a ContentPresenter for the header:

<HeaderedItemsControl ItemsSource="{Binding}" Header="Some text">
    <HeaderedItemsControl.Template>
        <ControlTemplate TargetType="HeaderedItemsControl">
            <Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="true">
                <DockPanel>
                    <ContentPresenter DockPanel.Dock="Top" ContentSource="Header" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                    <ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                </DockPanel>
            </Border>
        </ControlTemplate>
    </HeaderedItemsControl.Template>
</HeaderedItemsControl>

If you're only using it in one place, it might be easier to use a plain ItemsControl and include your header directly in the control template.

Also, it looks like you're trying to have two grids whose columns have the same width. You may want to look at Grid Size Sharing in WPF. If you set Grid.IsSharedSizeScope on a parent control then you can set SharedSizeGroup on columns of different grids to give them the same width.

Quartermeister
Thank you sir, your answer really helped.In the end I created a style for the HeaderedItemsControl and added the ContentPresenter as you suggested with the ContentSource = the header attribute. This way I can use it on all the ItemsControl's within the app and just add a grid with TextBlock's in the HeaderedItemsControl.Header tag.wrt your suggestion on the Grid Size sharing, I will test it but not sure if it will work as the one grid is in the DataTemplate and the other will be in the header of the the ItemsControl but I will test it and give feedback
Organ Grinding Monkey