2
votes

I have a WPF application which contains dynamically generated listbox items. I would like to disable the selection or "focusability" of the listbox items without disabling all of the controls in each listbox item (they contain buttons and links users need to be able to interact with). Below is a picture of what I'm trying to prevent:

enter image description here

This picture shows two listbox items. I have clicked on the background area of the top listbox item and selected it, which makes text harder to read and is just visually unappealing.

2
If you don't want selection then you can just use a simple ItemsControl and add a ScrollViewer in its style.Dmitry
dynamically generated listbox items sounds really odd and too winforms. you should use DataBinding, and yes, as @Didier said you need an ItemsControl instead of a ListBox.Federico Berasategui
I probably used the wrong terminology. The listbox items are presented via a databinding on an observable collection.user3342256
I have implemented ItemsControl instead of Listbox and it does disable selection - however it appears to have a drawback. Using ItemsControl, I had a <Style TargetType="{x:Type ListBoxItem}"> XAML section I was using to control borders, highlighting, etc. on individual listbox items upon mouseover events. Using ItemsControl, the styling gets applied to the entire list, not just a singluar item. I tried re-writing my styling using <Style TargetType="{x:Type ItemsControlItem}"> but that doesn't exist. Options?user3342256
The items of a simple ItemsControl are wrapped into a ContentPresenter. Unfortunatly it don't have a Template property.Dmitry

2 Answers

3
votes

You could set ListBoxItem.IsEnabled property to false like so:

<ListBox x:Name="_sampleListBox">
    <ListBox.ItemContainerStyle>
        <Style TargetType="ListBoxItem">
            <Setter Property="IsEnabled" Value="False"/>
        </Style>
    </ListBox.ItemContainerStyle>
</ListBox>

This would keep the items from being able to be selected. It may look kinda funny though... You could try using templates like so:

<ListBox x:Name="_sampleListBox">
    <ListBox.ItemContainerStyle>
        <Style TargetType="ListBoxItem">
            <Setter Property="IsEnabled" Value="False"/>
            <Style.Triggers>
                <Trigger Property="IsEnabled" Value="False">
                    <Setter Property="Foreground" Value="Red" />
                </Trigger>
            </Style.Triggers>
        </Style>
    </ListBox.ItemContainerStyle>
</ListBox>
3
votes

You can disable visual effects of the selection by using this ListBox:

<Style x:Key="NoSelectionListBoxItemStyle" TargetType="{x:Type ListBoxItem}">
    <Setter Property="Background" Value="Transparent"/>
    <Setter Property="HorizontalContentAlignment" Value="{Binding HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
    <Setter Property="VerticalContentAlignment" Value="{Binding VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
    <Setter Property="Padding" Value="2,0,0,0"/>
    <Setter Property="FocusVisualStyle">
        <Setter.Value>
            <Style>
                <!-- This removes focus visualization -->
                <Setter Property="Control.Template" Value="{x:Null}"/>
            </Style>
        </Setter.Value>
    </Setter>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type ListBoxItem}">
                <Border x:Name="Bd" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="true">
                    <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                </Border>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsEnabled" Value="false">
                        <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
                    </Trigger>
                                            <!-- Some default triggers removed to avoid background changes on selection -->
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Perhaps a cleaner solution would be to create your own ItemsControl with specific item containers that could have their style.