1
votes

I am creating a WPF custom control that inherits from ItemsControl. In the ControlTemplate of my control I have an ItemsPresenter. The problem is that I need to be able to get content in the items presenter to fill the entire content area. In the code below I have a simplified example of the broken code and also what I am trying to accomplish. BTW setting HorizontalAlignment and VerticalAlignment to Stretch causes the content expand horizontally but not vertically.

<Window x:Class="yada"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="768" Width="1024">
    <Grid>
        <Grid.Resources>
            <Style TargetType="Border" x:Key="stepBorder">
                <Setter Property="Background" Value="CadetBlue"></Setter>
                <Setter Property="BorderBrush" Value="Green" ></Setter>
                <Setter Property="BorderThickness" Value="2"></Setter>
                <Setter Property="Padding" Value="25"></Setter>
            </Style>
        </Grid.Resources>
        <TabControl Margin="0,20,0,0">
            <TabItem Header="Broken">
                <Border>
                    <ItemsControl>
                        <ItemsControl.Items>
                            <Control>
                                <Control.Template>
                                    <ControlTemplate>
                                        <Border Style="{StaticResource stepBorder}">
                                            <TextBlock Text="Border fills small region near the top"></TextBlock>
                                        </Border>
                                    </ControlTemplate>
                                </Control.Template>
                            </Control>
                        </ItemsControl.Items>
                    </ItemsControl>
                </Border>
            </TabItem>

            <TabItem Header="Works">
                <Border>
                    <Control>
                        <Control.Template>
                            <ControlTemplate>
                                <Border Style="{StaticResource stepBorder}" >
                                    <TextBlock Text="Border fills entire control"></TextBlock>
                                </Border>
                            </ControlTemplate>
                        </Control.Template>
                    </Control>
                </Border>
            </TabItem>
        </TabControl>
    </Grid>
</Window>

Here is some code from my control. I cant include it all, there is too much. I think this is the relevant part however:

    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:Wizard}">
                <Border Background="{TemplateBinding Background}"
                        BorderBrush="{TemplateBinding BorderBrush}"
                        BorderThickness="{TemplateBinding BorderThickness}">
                    <Grid>
                        <Grid.RowDefinitions>
                            <RowDefinition Height="*" x:Name="ContentRow" />
                            <RowDefinition Height="{Binding ElementName= NavButtonPanel,Path=ActualHeight}"></RowDefinition>
                        </Grid.RowDefinitions>
                        <ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto" x:Name="ContentScrollViewer" MaxHeight="{Binding ElementName=ContentRowHeight, Path=ActualHeight}">
                            <ItemsPresenter 
                                x:Name="Presenter" 
                                VerticalAlignment="{TemplateBinding VerticalContentAlignment}" 
                                HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}">
                            </ItemsPresenter>
                        </ScrollViewer>

                        <Border Style="{TemplateBinding NavButtonPanelStyle}" Grid.Row="1" x:Name="NavButtonPanel">
                        <StackPanel Orientation="Horizontal" HorizontalAlignment="Right" >
                        </StackPanel>
                        </Border>
                    </Grid>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
    <Setter Property="ItemTemplate">
        <Setter.Value>
            <DataTemplate></DataTemplate>
        </Setter.Value>
    </Setter>
1

1 Answers

2
votes

As usual, just posting on SO gets me halfway to my answer.

It turns out the ItemsControl is using an evil stackpanel as a container for items. Fortunately there is a top-secret property called ItemsPanel that lets you change this. Just set it to a grid as shown below and you are in business.

In my case I am writing a custom control that inherits from ItemsControl so in the Style I add this property setter:

    <Setter Property="ItemsPanel">
        <Setter.Value>
            <ItemsPanelTemplate>
                <Grid></Grid>
            </ItemsPanelTemplate>
        </Setter.Value>
    </Setter>