WPF: désactiver ListBox, mais activer scrolling

<!-- Je me suis cogné la tête contre ça toute la matinée.

fondamentalement, j'ai une listbox, et je veux empêcher les gens de changer la sélection pendant un long processus, mais leur permettre de continuer à faire défiler.

Solution:

toutes les réponses étaient bonnes, je suis allé avec avalant événements de souris puisque c'était le plus simple en avant. J'ai câblé PreviewMouseDown et PreviewMouseUp à un seul événement, qui a vérifié mon arrière-plan de travail.IsBusy, et si il a été mis sur la Ishandled propriété sur l'événement args à true.

8
demandé sur Matt Briggs 2009-02-09 20:42:06

10 réponses

l'astuce est de ne pas vraiment désactiver. Désactiver verrouillera tous les messages de la boîte de défilement.

pendant la longue opération, gray out le texte dans la boîte de liste en utilisant its .Propriété de ForeColor et avalent tous les clics de souris. Cela simulera la désactivation de la commande et permettra le défilement sans entrave.

1
répondu Yes - that Jake. 2009-02-09 17:50:24

si vous regardez dans le modèle de contrôle de la ListBox, il y a une barre de défilement et ItemsPresenter à l'intérieur. Donc, faites le ItemsPresenter désactivé et vous obtiendrez cela facilement. Utilisez le Style de cloche sur le ListBox et vous êtes bon à aller.

    <Style x:Key="disabledListBoxWithScroll" TargetType="{x:Type ListBox}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type ListBox}">
                    <Border x:Name="Bd" SnapsToDevicePixels="true" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Padding="1">
                        <ScrollViewer Padding="{TemplateBinding Padding}" Focusable="false">
                            <ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" IsEnabled="False" IsHitTestVisible="True"/>
                        </ScrollViewer>
                    </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>

sur la liste, utilisez le Style

<ListBox    Style="{DynamicResource disabledListBoxWithScroll}" ..... />
8
répondu Jobi Joy 2009-02-09 18:19:41

désolé cela fait presque deux ans, mais je pense que cette solution qui utilise DataTrigger est encore plus simple. comment désactiver un élément ListBox basé sur une valeur de propriété?

2
répondu Shuo 2017-05-23 12:16:56

j'ai trouvé que mettre une liste désactivée dans un ScrollViewer avec auto scrolling activé donne l'effet désiré.

2
répondu Konrad 2013-02-26 12:38:40

bien que ce soit pour Silverlight, peut-être que ce billet de blog vous aidera à aller dans la bonne direction? Silverlight Pas de Sélection de zone de liste et ViewBox

1
répondu Andy 2009-02-09 17:49:56

j'ai utilisé cette solution, c'est vraiment facile et fonctionne parfaitement:

pour chaque SurfaceListBoxItem item vous mettre dans le Listbox, faire ceci:

item.IsHitTestVisible = false;
1
répondu Oskar 2012-12-20 13:10:34

une autre option à considérer est la désactivation des ListBoxItems. Cela peut être fait en définissant L'ItemContainerStyle comme indiqué dans l'extrait suivant.

<ListBox ItemsSource="{Binding YourCollection}">
    <ListBox.ItemContainerStyle>
        <Style TargetType="ListBoxItem">
            <Setter Property="IsEnabled" Value="False" />
        </Style>
    </ListBox.ItemContainerStyle>
</ListBox>

si vous ne voulez pas que le texte soit gris, vous pouvez spécifier la couleur désactivée en ajoutant un pinceau aux ressources du style avec la touche suivante: {x:Static SystemColors.GrayTextBrushKey}. L'autre solution serait d'Outrepasser le modèle de contrôle ListBoxItem.

Cette question est à peu près la même comme celui-ci: Il n'y a pas de zone de liste.SelectionMode= "None", y a-t-il une autre façon de désactiver la sélection dans une liste? et ma réponse est la même.

0
répondu Caleb Vear 2017-05-23 11:53:14

j'ai trouvé une solution très simple et simple en travaillant pour moi, j'espère qu'elle ferait aussi bien pour vous

<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
     <Setter Property="Focusable" Value="False"/>
 </Style>

0
répondu Asad Durrani 2012-01-17 11:52:16

une réponse complète en utilisant http://www.codeproject.com/Tips/60619/Scrollable-Disabled-ListBox-in-WPF

Du Style:

<Style TargetType="{x:Type local:CustomListBox}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:CustomListBox}">
                <Border SnapsToDevicePixels="true" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Padding="1">
                    <ScrollViewer IsEnabled="True">
                        <ItemsPresenter IsEnabled="{Binding Path=IsEnabledWithScroll,  RelativeSource={RelativeSource TemplatedParent}}"  SnapsToDevicePixels="{TemplateBinding  UIElement.SnapsToDevicePixels}"/>
                    </ScrollViewer>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

La classe

public class CustomListBox : ListBox
{
    public bool IsEnabledWithScroll
    {
        get { return (bool)GetValue(IsEnabledWithScrollProperty); }
        set { SetValue(IsEnabledWithScrollProperty, value); }
    }

    public static readonly DependencyProperty IsEnabledWithScrollProperty =
        DependencyProperty.Register("IsEnabledWithScroll", typeof(bool), typeof(CustomListBox), new UIPropertyMetadata(true));
}

puis à la place de setted IsEnabled sur la ListBox, utilisez IsEnabledWithScroll à la place. Le défilement fonctionnera si la liste de diffusion est activée ou désactivée.

0
répondu Chris Klepeis 2016-03-08 13:39:16

il semble y avoir plusieurs façons d'écorcher ce chat en particulier. J'ai trouvé que par la configuration de IsHitTestVisible sur le ItemsContainerStyle dans le code XAML j'ai exactement ce dont j'avais besoin:

<ListBox IsHitTestVisible="true" ScrollViewer.VerticalScrollBarVisibility="Auto" ScrollViewer.CanContentScroll="True">
    <ListBox.ItemContainerStyle>
        <Style TargetType="ListBoxItem">
            <Setter Property="IsHitTestVisible" Value="False" />
        </Style>
    </ListBox.ItemContainerStyle>
</ListBox>
0
répondu BrianVPS 2017-10-05 18:18:23