Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Where are the margins/padding set on a wpf ListView GridView?

I've got a WPF ListView/GridView spec'd in XAML. The first column uses a CellTemplate to specify icons and the others use DisplayMemberBinding to populate themselves. The icons column is 20 wide, the icons 16 but they're getting truncated by margins/padding/something. I can't work out where it's set.

Here's the essentials (I've removed some columns because they're the same):

<ListView.ItemContainerStyle>
    <Style TargetType="{x:Type ListViewItem}">
        <Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" />
        <Setter Property="FontWeight" Value="Normal" />
        <Style.Triggers>
            <Trigger Property="IsSelected" Value="True">
                <Setter Property="FontWeight" Value="Bold" />
            </Trigger>
        </Style.Triggers>
    </Style>
</ListView.ItemContainerStyle>

<ListView.Resources>
    <DataTemplate x:Key="image">
        <Image Width="16" Height="16" Margin="0,0,0,0"
                          HorizontalAlignment="Center"
                          Source="{Binding Path=ObjectType, 
                                           Converter={StaticResource imageConverter} }" />
    </DataTemplate>
</ListView.Resources>

<ListView.View>
    <GridView>
        <GridViewColumn Width="20"
                        CellTemplate="{StaticResource image}"/>
        <GridViewColumn Width="120" Header="Name"
                        DisplayMemberBinding="{Binding Path=Name}"/>
    </GridView>
</ListView.View>

ImageConverter just turns an ObjectType into an image so each type of item gets its own icon.

like image 801
serialhobbyist Avatar asked Aug 29 '09 14:08

serialhobbyist


1 Answers

Many features of the GridView are hard-coded into the class. In particular the GridViewRowPresenter creates either a hard-coded TextBlock or ContentPresenter container for each of the cells and forces the margins to 6,0,6,0 whether you like it or not.

Normally I would discourage you from anything that involves hard-coding a negative margin to compensate as it's a hack layered on another hack. However, after disassembling the GridViewRowPresenter, there are no other options.

My first attempt was to override the implicit style for the container control that was created in the GridViewRowPresenter class, but that control is a TextBox or a ContentPresenter which has no template to override.

My second attempt was to disassemble the code and build a new GridViewRowPresenter. I'm afraid there are just too many incestuous 'internal' calls in the class to make this a workable solution.

A smarter architect would have provided a DependencyProperty that allowed the user of the class to override the container that was created for each cell. For some reason they allowed this with the headers but not the actual cell contents.

So we are left with the fact that the cells in a GridRowPresenter can neither be overridden, reverse engineered, nor templated. I'm sorry, but the negative margins is the best that can be done with this class.

We need a better ListView: the GridView is not suitable for a lookless interface though I appreciate what they original architects were trying to do by divorcing the ItemsPresenter from the presentation.

like image 173
Quarkly Avatar answered Sep 30 '22 13:09

Quarkly