WPF: désactiver ListBox, mais activer scrolling
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.
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.
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}" ..... />
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é?
j'ai trouvé que mettre une liste désactivée dans un ScrollViewer avec auto scrolling activé donne l'effet désiré.
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
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;
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.
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>
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.
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>