2009-02-09 6 views
7

Hatte gegen den ganzen Morgen meinen Kopf gegen diesen Kopf.WPF: Deaktivieren Sie ListBox, aber aktivieren Sie Scrollen

Grundsätzlich habe ich eine Listbox, und ich möchte verhindern, dass Menschen die Auswahl während eines langen Prozesses ändern, aber erlauben Sie ihnen noch zu scrollen.

Lösung:

Alle Antworten waren gut, ich ging mit Maus-Ereignisse beim Schlucken, da dies die direkteste war. Ich verdrahtete PreviewMouseDown und PreviewMouseUp auf ein einzelnes Ereignis, das meine backgroundWorker.IsBusy überprüfte, und wenn es festgelegt wurde, wird die IsHandled-Eigenschaft für das Ereignis auf True festgelegt.

Antwort

1

Der Trick ist, nicht wirklich zu deaktivieren. Durch das Deaktivieren werden alle Nachrichten aus dem Bildlauffeld gesperrt.

Während der langen Operation, grau den Text im Listenfeld mit seiner .ForeColor -Eigenschaft und schlucken Sie alle Mausklicks. Dies simuliert das Deaktivieren des Steuerelements und ermöglicht ungehindertes Scrollen.

+3

Das Problem mit diesem Ansatz ist, dass die Tastatur immer noch verwendet werden kann, um Auswahl treffen –

+0

Also Schluck Tastenanschläge Ereignisse? – Michael

+0

Ja das ist nicht wirklich eine gute Antwort, ich würde das nicht tun. – Yusha

8

Wenn Sie in die Steuerelementvorlage der ListBox schauen, gibt es eine ScrollBar und ItemsPresenter innerhalb. So machen Sie den ItemsPresenter deaktiviert und Sie werden es leicht bekommen. Verwenden Sie den Balg Style auf der ListBox und Sie können loslegen.

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

Auf der List-Box verwenden Sie den Style

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

ich diese Lösung verwendet, es ist wirklich einfach und funktioniert perfekt:

Für jeden SurfaceListBoxItem item Sie in den Listbox setzen, dies zu tun:

item.IsHitTestVisible = false; 
+0

Dies funktioniert perfekt, obwohl keine Interaktionssteuerungen in einem Element vorhanden sind, da diese Steuerelemente andernfalls nicht funktionieren. – jarvanJiang

0

Eine weitere erwägenswerte Option ist das Deaktivieren der ListBoxItems. Dies kann durch Festlegen des ItemContainerStyle wie im folgenden Codefragment gezeigt erfolgen.

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

Wenn Sie den Text, den Sie die deaktivierte Farbe angeben nicht wollen grau sein kann mit einem Pinsel auf den Stil der Ressourcen mit dem folgenden Schlüssel durch Zugabe: {x: Static SystemColors.GrayTextBrushKey}. Die andere Lösung wäre, die ListBoxItem-Steuerelementvorlage zu überschreiben.

Diese Frage ist so ziemlich die gleiche wie diese: There ain't ListBox.SelectionMode=“None”, is there another way to disable selection in a listbox? und meine Antwort ist die gleiche.

0

ich eine sehr einfach und geradlinig Lösung arbeitet für mich gefunden, ich hoffe es auch

gefunden für Sie tun würde
<ListBox.ItemContainerStyle> 
<Style TargetType="{x:Type ListBoxItem}"> 
    <Setter Property="Focusable" Value="False"/> 
</Style> 

2

ich, dass ein behindertes ListBox in einem Scrollviewer mit automatischer Scroll-Putting aktiviert gibt den gewünschten Effekt.

+0

Was? Dies funktioniert nicht. – Yusha

0

Eine vollständige Antwort http://www.codeproject.com/Tips/60619/Scrollable-Disabled-ListBox-in-WPF

Den Stil mit:

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

Die Klasse

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

Dann statt gefasste IsEnabled auf der List-Box verwenden IsEnabledWithScroll statt. Scrollen funktioniert, wenn das Listenfeld aktiviert oder deaktiviert ist.

0

Es scheint viele Möglichkeiten zu geben, diese bestimmte Katze zu häuten. Ich fand, dass IsHitTestVisible auf den ItemsContainerStyle in XAML, indem bekam ich genau das, was ich brauchte:

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