2009-02-09 18 views
7

He estado golpeando mi cabeza contra esto toda la mañana.WPF: deshabilita ListBox, pero habilita el desplazamiento

Básicamente, tengo un cuadro de lista, y quiero evitar que las personas cambien la selección durante un proceso largo, pero les permite desplazarse.

Solución:

Todas las respuestas eran buenas, fui con la deglución eventos de ratón, ya que era el más sencillo. Conecté PreviewMouseDown y PreviewMouseUp a un solo evento, que verificó mi backgroundWorker.IsBusy, y si se configuró la propiedad IsHandled en el evento args en verdadero.

Respuesta

1

El truco es no deshabilitar realmente. La desactivación bloqueará todos los mensajes del cuadro de desplazamiento.

Durante la operación larga, apague el texto en el cuadro de lista utilizando su propiedad .ForeColor y trague todos los clics del mouse. Esto simulará deshabilitar el control y permitir el desplazamiento sin obstáculos.

+3

El problema con este enfoque es que el teclado se puede seguir utilizando para hacer selecciones –

+0

¿Así que tragar los eventos de pulsación de tecla? – Michael

+0

Sí, esta no es realmente una buena respuesta, yo no haría esto. – Yusha

8

Si observa la plantilla de control de ListBox, hay un ScrollBar y ItemsPresenter dentro. Por lo tanto, haga que ItemsPresenter esté desactivado y lo obtendrá fácilmente. Usa el estilo de abajo en el ListBox y estás listo para empezar.

<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> 

En el cuadro de lista utilizar el estilo

<ListBox Style="{DynamicResource disabledListBoxWithScroll}" ..... /> 
1

he utilizado esta solución, que es muy fácil y funciona perfectamente:

Por cada SurfaceListBoxItem item se pone en el Listbox, hacer esto:

item.IsHitTestVisible = false; 
+0

Este trabajo es perfecto, mientras que no hay controles de interacción en el elemento, de lo contrario esos controles no podrán. – jarvanJiang

0

Otra opción que vale la pena considerar es la desactivación de ListBoxItems. Esto puede hacerse configurando ItemContainerStyle como se muestra en el siguiente fragmento.

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

Si no desea que el texto sea de color gris puede especificar el color con discapacidad mediante la adición de un cepillo a los recursos del estilo con la siguiente clave: {x: Estático SystemColors.GrayTextBrushKey}. La otra solución sería anular la plantilla de control ListBoxItem.

Esta pregunta es muy similar a esta: There ain't ListBox.SelectionMode=“None”, is there another way to disable selection in a listbox? y mi respuesta es la misma.

0

he encontrado una solución hacia adelante muy simple y sencillo que trabaja para mí, espero que haría por ti, así

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

2

encontré que poner un cuadro de lista con discapacidad en una ScrollViewer con el desplazamiento automático habilitado da el efecto deseado.

+0

¿Qué? Esto no funciona – Yusha

0

Una respuesta completa usando http://www.codeproject.com/Tips/60619/Scrollable-Disabled-ListBox-in-WPF

El Estilo:

<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 clase

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)); 
} 

Entonces, en lugar de enchufar IsEnabled en el cuadro de lista, utilice IsEnabledWithScroll lugar. El desplazamiento funcionará si el cuadro de lista está habilitado o deshabilitado.

0

Parece que hay muchas maneras de desollar a este gato en particular. He descubierto que mediante el establecimiento de IsHitTestVisible en el ItemsContainerStyle en XAML me dieron exactamente lo que necesitaba:

<ListBox IsHitTestVisible="true" ScrollViewer.VerticalScrollBarVisibility="Auto" ScrollViewer.CanContentScroll="True"> 
    <ListBox.ItemContainerStyle> 
     <Style TargetType="ListBoxItem"> 
      <Setter Property="IsHitTestVisible" Value="False" /> 
     </Style> 
    </ListBox.ItemContainerStyle> 
</ListBox> 
Cuestiones relacionadas