Search code examples
c#wpfxamllistviewwindows-8

Visibility.Collapse doesn't fully collapse item on Win8


Im doing a filter for items in listview control. When item is supposed to be filtered out im changing visibility for that item to Visibility.Collapsed.

While in Windows 7 it works great:
Win7 http://www.imagebam.com/image/4c8cab240432140

On Windows 8 Collapsed item does not fully collapse, and leaves about ~4pixels of empty space:
Win7 http://www.imagebam.com/image/6ab32b240431990

XAML Item template:

<ListView.ItemTemplate>
    <DataTemplate DataType="ItemOfInterest">
        <DockPanel Visibility="{Binding Visible}">
            <StackPanel DockPanel.Dock="Top" Orientation="Horizontal">
                <TextBlock FontSize="15" Padding="1,0,0,0" TextWrapping="NoWrap" Text="{Binding Path=Title}" Foreground="{Binding Color}"></TextBlock>
                <TextBlock FontSize="11" Padding="10,0,0,0" VerticalAlignment="Bottom" TextWrapping="Wrap" Foreground="Gray" Text="{Binding Path=Owner}"></TextBlock>
                <TextBlock FontSize="12" Padding="10,0,0,0" VerticalAlignment="Bottom" TextWrapping="Wrap" Foreground="White" Text="{Binding Path=StashName}"></TextBlock>
                <TextBlock FontSize="11" Padding="10,0,0,0" VerticalAlignment="Bottom" TextWrapping="Wrap" Foreground="Gray" Text="{Binding Path=StashPos}"></TextBlock>
            </StackPanel>
            <TextBlock DockPanel.Dock="Bottom" FontSize="11" Padding="10,0,0,0" Visibility="{Binding DisplayExtraLine}" TextWrapping="Wrap" Foreground="Gray" Text="{Binding Path=ExtraLine}"></TextBlock>
        </DockPanel>
    </DataTemplate>
</ListView.ItemTemplate>

Any ideas what's causing this? Or the only way to bypass this, is by removing items from the list when they are being filtered out?


Solution

  • If you use Snoop you will be able to see that each ListViewItem is inside a Border with a height of 4. So when you collapse the DockPanel the Border still has a height of 4.

    The solution is create an ItemContainerStyle and hide the Border as well as or instead of the child DockPanel.

    Here's my solution. My Visible property is a bool which is why I need the converter.

    <Grid.Resources>
        <Style x:Key="ItemContainerStyle" TargetType="{x:Type ListViewItem}">
            <Setter Property="Visibility" 
                    Value="{Binding Visible, 
                            Converter={StaticResource BoolToVisibility}}"/>
        </Style>
    </Grid.Resources>
    
    <Grid.ColumnDefinitions>
        <ColumnDefinition/>
        <ColumnDefinition/>
    </Grid.ColumnDefinitions>
    
    <ListView ItemsSource="{Binding Items}" 
              ItemContainerStyle="{StaticResource ItemContainerStyle}">
        <ListView.ItemTemplate>
            <DataTemplate DataType="wpfSampleExplorer:ItemOfInterest">
                <DockPanel>
                    <StackPanel DockPanel.Dock="Top" Orientation="Horizontal">
                        <TextBlock FontSize="15" Text="{Binding Path=Title}"/>>
                    </StackPanel>
                </DockPanel>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>