6

Could anyone suggest how I can implement a WPF ListBox that (effectively) has a transparent/hit-test-invisible background, but whose items are still hit-test-visible?

In other words, I'd like to be able to click - through the ListBox's background - to controls underneath it, but still be able to select the ListBox's items.

I have ListBox using a custom layout panel (it's a ListBox because the items need to be selectable). However, I need this panel to be overlayed on top of other controls, allowing them to still be used normally.

I've tried various combinations of Background="Transparent" and IsHitTestVisible="False" but I suspect I might be on the wrong lines...

Hope this makes sense - I'm new to WPF so any guidance will be most appreciated! Thanks.

FuzzyLogic
  • 123
  • 2
  • 7

1 Answers1

7

Try setting the background to "{x:Null} on the ListeItemContainer and the ListBox itself.

Transparent is still hit-testable, which is why you're still getting hit tests on it.

EDIT

I ran WPF Inspector on a sample and found that the ScrollViewer in the default ListBox template was causing mouse clicks to stay in the ListBox.

Here is a ListBox control template that does not include the ScrollViewer. It does allow the mouse to pass through to the TextBox that is behind the listbox, but still allows the user to select items in the listbox.

<Window
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  >
  <Window.Resources>
        <SolidColorBrush x:Key="ListBorder" Color="#828790"/>
        <Style x:Key="ListBoxStyle1" TargetType="{x:Type ListBox}">
            <Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"/>
            <Setter Property="BorderBrush" Value="{StaticResource ListBorder}"/>
            <Setter Property="BorderThickness" Value="1"/>
            <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
            <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto"/>
            <Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
            <Setter Property="ScrollViewer.CanContentScroll" Value="true"/>
            <Setter Property="Stylus.IsFlicksEnabled" Value="False"/>
            <Setter Property="VerticalContentAlignment" Value="Center"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type ListBox}">
                        <Border x:Name="Bd" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Padding="1" SnapsToDevicePixels="true">
                            <ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
                        </Border>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsEnabled" Value="false">
                                <Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>
                            </Trigger>
                            <Trigger Property="IsGrouping" Value="true">
                                <Setter Property="ScrollViewer.CanContentScroll" Value="false"/>
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>  
  </Window.Resources>
  <Grid Width="100">
    <TextBox TextWrapping="Wrap">I'm in the background. I'm in the background. I'm in the backgroun.</TextBox>
    <ListBox Background="{x:Null}" Style="{StaticResource ListBoxStyle1}">
      <ListBoxItem Margin="10" Background="#999">Hello</ListBoxItem>
      <ListBoxItem Margin="10" Background="#999">Hello</ListBoxItem>
      <ListBoxItem Margin="10" Background="#999">Hello</ListBoxItem>
      <ListBoxItem Margin="10" Background="#999">Hello</ListBoxItem>
    </ListBox>
  </Grid>
</Window>
NathanAW
  • 3,329
  • 18
  • 19
  • Thanks @Nathan - I tried it but that doesn't seem to work either. Nothing underneath is clickable unless I set `IsHitTestVisible="False"`, but of course that means the items are not selectable... – FuzzyLogic Jul 11 '11 at 21:57
  • Try using a tool like Christian Moser's WPF Inspector ( http://www.wpftutorial.net/inspector.html ) to see what layers / controls are being rendered by the ListBox. This should help you locate the layer that needs to have a null background. – NathanAW Jul 12 '11 at 10:59
  • I looked into this with WPF Inspector and found the ScrollViewer in the ListBox to be the issue. Above is a sample that removes the ScrollViewer from the ListBox template. It seems to work as you asked. – NathanAW Jul 12 '11 at 11:34
  • Brilliant! That's great Nathan, thanks very much. Just been looking at WPF Inspector and Snoop (which I didn't know about) but never considered the ScrollViewer. Cheers! – FuzzyLogic Jul 12 '11 at 13:39