2009-02-09 15 views
7

State sbattendo la testa contro questo per tutta la mattinata.WPF: disabilita ListBox, ma abilita lo scrolling

Fondamentalmente, ho una casella di riepilogo e desidero impedire alle persone di modificare la selezione durante un lungo processo in esecuzione, ma consentire loro di continuare a scorrere.

Soluzione:

Tutte le risposte sono state buone, sono andato con la deglutizione eventi del mouse dato che era la più semplice. Ho collegato PreviewMouseDown e PreviewMouseUp a un singolo evento, che ha verificato il mio backgroundWorker.IsBusy e, se è stato impostato, la proprietà IsHandled sull'argomento è vera.

risposta

1

Il trucco è non disabilitare. La disabilitazione bloccherà tutti i messaggi dalla casella di scorrimento.

Durante l'operazione lunga, ombreggia il testo nella casella di riepilogo utilizzando la proprietà .ForeColor e ingoia tutti i clic del mouse. Questo simulerà la disattivazione del controllo e consentirà lo scorrimento senza impedimenti.

+3

Il problema di questo approccio è che la tastiera può ancora essere utilizzato per fare selezioni –

+0

Quindi ingoiare gli eventi di pressione del tasto? – Michael

+0

Sì, questa non è davvero una buona risposta, non lo farei. – Yusha

8

Se si guarda nel modello di controllo del ListBox, all'interno c'è una barra di scorrimento e un oggetto Items. Quindi rendi gli oggetti disattivati ​​e otterrai questo facilmente. Usa lo stile muggito sul ListBox e sei a posto.

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

Sulla ListBox usare lo stile

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

Ho usato questa soluzione, è davvero facile e funziona perfettamente:

Per ogni SurfaceListBoxItem item si mette in Listbox, fare questo:

item.IsHitTestVisible = false; 
+0

Questo lavoro è perfetto anche se non ci sono controlli di interazione nell'elemento, altrimenti tali controlli non saranno disponibili. – jarvanJiang

0

Un'altra opzione da prendere in considerazione è la disattivazione di ListBoxItems. Questo può essere fatto impostando ItemContainerStyle come mostrato nel seguente snippet.

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

Se non si desidera che il testo sia grigio è possibile specificare il colore disattivato con l'aggiunta di un pennello per le risorse dello stile con la seguente chiave: {x: Statico SystemColors.GrayTextBrushKey}. L'altra soluzione sarebbe sostituire il modello di controllo ListBoxItem.

Questa domanda è più o meno la stessa di questa: There ain't ListBox.SelectionMode=“None”, is there another way to disable selection in a listbox? e la mia risposta è la stessa.

0

ho trovato una soluzione molto semplice e dritto in avanti a lavorare per me, spero che farebbe per voi pure

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

2

ho scoperto che mettere un ListBox disabile in ScrollViewer con lo scorrimento automatico abilitato dà l'effetto desiderato.

+0

Cosa? Questo non funziona. – Yusha

0

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

Lo Stile:

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

Poi, invece di impostato IsEnabled sulla ListBox, utilizzare invece IsEnabledWithScroll. Lo scorrimento funzionerà se la casella di riepilogo è abilitata o disabilitata.

0

Sembra che ci siano molti modi per skinare questo particolare gatto. Ho scoperto che impostando IsHitTestVisible sulla ItemsContainerStyle in XAML Ho ottenuto esattamente quello che mi serviva:

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