Search code examples
xamllistviewuwpuwp-xamltemplating

How do I remove the margins/padding and enable full width for a grouped ListView in UWP?


I have a ListView that is grouped with headers. I have one UserControl for the header <local:MyHeaderUserControl /> that displays the header using a text block <TextBlock Text="{Binding Key}" /> and another UserControl for each entry <local:MyListItemUserControl> that binds to the listed object.

I want to display them full width with no margins. ListView in UWP inserts annoying margins, divider lines and by default aligns left and it is not clear which properties I have to set on which of the many possible templates will remove those.

What is the minimal template for doing this?

Note: I have already worked this out and am hoping to post for reference when I can but am happy to let someone else get the karma if they get there first ;)


Solution

  • This is the most minimal template I could find, but it also removes the default styling for focus, selection, animations etc. which would all have to be handled in the custom UserControls ...

    <ListView
        ItemsSource="{Binding Source={StaticResource collectionViewSource}}"
        >
        <ListView.ItemContainerStyle>
            <Style TargetType="ListViewItem">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="ListViewItem">
                            <local:MyListItemUserControl />
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </ListView.ItemContainerStyle>
        <ListView.GroupStyle>
            <GroupStyle>
                <GroupStyle.HeaderContainerStyle>
                    <Style TargetType="ListViewHeaderItem">
                        <Setter Property="Margin" Value="0" />
                        <Setter Property="Padding" Value="0" />
                        <Setter Property="Template">
                            <Setter.Value>
                                <ControlTemplate TargetType="ListViewHeaderItem">
                                    <local:MyHeaderUserControl />
                                </ControlTemplate>
                            </Setter.Value>
                        </Setter>
                    </Style>
                </GroupStyle.HeaderContainerStyle>
            </GroupStyle>
        </ListView.GroupStyle>
    </ListView>
    

    Alternatively, this template preserves the default behaviours for clicking, selecting etc. whilst removing the margins and making the controls full width ...

    <ListView
        ItemsSource="{Binding Source={StaticResource collectionViewSource}}"
        >
        <ListView.ItemTemplate>
            <DataTemplate>
                <!-- This is marginless and full width! -->
                <local:MyListItemUserControl />
            </DataTemplate>
        </ListView.ItemTemplate>
        <ListView.ItemContainerStyle>
            <Style TargetType="ListViewItem">
                <Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}"/>
                <Setter Property="FontSize" Value="{ThemeResource ControlContentThemeFontSize}"/>
                <Setter Property="Background" Value="{ThemeResource ListViewItemBackground}"/>
                <Setter Property="Foreground" Value="{ThemeResource ListViewItemForeground}"/>
                <Setter Property="TabNavigation" Value="Local"/>
                <Setter Property="IsHoldingEnabled" Value="True"/>
                <Setter Property="Padding" Value="0"/>
                <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
                <Setter Property="VerticalContentAlignment" Value="Center"/>
                <Setter Property="MinWidth" Value="{ThemeResource ListViewItemMinWidth}"/>
                <Setter Property="MinHeight" Value="0"/>
                <Setter Property="AllowDrop" Value="False"/>
                <Setter Property="UseSystemFocusVisuals" Value="True"/>
                <Setter Property="FocusVisualMargin" Value="0"/>
                <Setter Property="FocusVisualPrimaryBrush" Value="{ThemeResource ListViewItemFocusVisualPrimaryBrush}"/>
                <Setter Property="FocusVisualPrimaryThickness" Value="2"/>
                <Setter Property="FocusVisualSecondaryBrush" Value="{ThemeResource ListViewItemFocusVisualSecondaryBrush}"/>
                <Setter Property="FocusVisualSecondaryThickness" Value="1"/>
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="ListViewItem">
                            <ListViewItemPresenter CheckBrush="{ThemeResource ListViewItemCheckBrush}" ContentMargin="{TemplateBinding Padding}" CheckMode="{ThemeResource ListViewItemCheckMode}" ContentTransitions="{TemplateBinding ContentTransitions}" CheckBoxBrush="{ThemeResource ListViewItemCheckBoxBrush}" DragForeground="{ThemeResource ListViewItemDragForeground}" DragOpacity="{ThemeResource ListViewItemDragThemeOpacity}" DragBackground="{ThemeResource ListViewItemDragBackground}" DisabledOpacity="{ThemeResource ListViewItemDisabledThemeOpacity}" FocusVisualPrimaryBrush="{TemplateBinding FocusVisualPrimaryBrush}" FocusVisualSecondaryThickness="{TemplateBinding FocusVisualSecondaryThickness}" FocusBorderBrush="{ThemeResource ListViewItemFocusBorderBrush}" FocusVisualMargin="{TemplateBinding FocusVisualMargin}" FocusVisualPrimaryThickness="{TemplateBinding FocusVisualPrimaryThickness}" FocusSecondaryBorderBrush="{ThemeResource ListViewItemFocusSecondaryBorderBrush}" FocusVisualSecondaryBrush="{TemplateBinding FocusVisualSecondaryBrush}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" Control.IsTemplateFocusTarget="True" PointerOverForeground="{ThemeResource ListViewItemForegroundPointerOver}" PressedBackground="{ThemeResource ListViewItemBackgroundPressed}" PlaceholderBackground="{ThemeResource ListViewItemPlaceholderBackground}" PointerOverBackground="{ThemeResource ListViewItemBackgroundPointerOver}" ReorderHintOffset="{ThemeResource ListViewItemReorderHintThemeOffset}" SelectedPressedBackground="{ThemeResource ListViewItemBackgroundSelectedPressed}" SelectionCheckMarkVisualEnabled="{ThemeResource ListViewItemSelectionCheckMarkVisualEnabled}" SelectedForeground="{ThemeResource ListViewItemForegroundSelected}" SelectedPointerOverBackground="{ThemeResource ListViewItemBackgroundSelectedPointerOver}" SelectedBackground="{ThemeResource ListViewItemBackgroundSelected}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
    
        </ListView.ItemContainerStyle>
        <ListView.GroupStyle>
            <GroupStyle>
                <GroupStyle.HeaderTemplate>
                    <DataTemplate>
                        <!-- This is marginless and full width! -->
                        <local:MyHeaderUserControl />
                    </DataTemplate>
                </GroupStyle.HeaderTemplate>
                <GroupStyle.HeaderContainerStyle>
                    <Style TargetType="ListViewHeaderItem">
                        <Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}"/>
                        <Setter Property="FontSize" Value="{ThemeResource ListViewHeaderItemThemeFontSize}"/>
                        <Setter Property="Background" Value="{ThemeResource ListViewHeaderItemBackground}"/>
                        <Setter Property="Margin" Value="0"/>
                        <Setter Property="Padding" Value="0"/>
                        <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
                        <Setter Property="VerticalContentAlignment" Value="Top"/>
                        <Setter Property="MinHeight" Value="0"/>
                        <Setter Property="UseSystemFocusVisuals" Value="True"/>
                        <Setter Property="Template">
                            <Setter.Value>
                                <ControlTemplate TargetType="ListViewHeaderItem">
                                    <StackPanel BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}">
                                        <ContentPresenter x:Name="ContentPresenter" ContentTemplate="{TemplateBinding ContentTemplate}" ContentTransitions="{TemplateBinding ContentTransitions}" Content="{TemplateBinding Content}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
                                    </StackPanel>
                                </ControlTemplate>
                            </Setter.Value>
                        </Setter>
                    </Style>
                </GroupStyle.HeaderContainerStyle>
            </GroupStyle>
        </ListView.GroupStyle>
    </ListView>