views:

751

answers:

3

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.

A: 

Use Snoop to figure out which element is responsible for imposing the extra spacing. Mouse over the space and hold down control and shift. The element will then be highlighted in the visual tree.

HTH, Kent

Kent Boogaart
Nice one, thanks.
serialhobbyist
A: 

by default, each cell has a hardcoded margin of 6,0. Probably that's your problem. You can override this behaviour by setting a margin of -6,0 in your celltemplate

federubin
+2  A: 

The above post is not an answer, it is a hack. The Original Poster has a very valid question: what controls the padding/margins in a GridView. It turns out 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.

DRAirey1