views:

3099

answers:

5

Been banging my head against this all morning.

Basically, I have a listbox, and I want to keep people from changing the selection during a long running process, but allow them to still scroll.

Solution:

All the answers were good, I went with swallowing mouse events since that was the most straight forward. I wired PreviewMouseDown and PreviewMouseUp to a single event, which checked my backgroundWorker.IsBusy, and if it was set the IsHandled property on the event args to true.

+1  A: 

While it's for Silverlight, maybe this blog post would help you get going in the right direction? Silverlight No Selection ListBox and ViewBox

Andy
This was perfect for me, thanks for posting the link
Guy Starbuck
+2  A: 

The trick is to not really disable. Disabling will lock out all messages from the scroll box.

During the long operation, gray out the text in the list box using its .ForeColor property and swallow all mouse clicks. This will simulate disabling the control and allow scrolling unimpeded.

Jekke
+1  A: 

If you look in to the control template of the ListBox, there is a ScrollBar and ItemsPresenter inside. So Make the ItemsPresenter Disabled and you will get this easily. Use the bellow Style on the ListBox and you are good to go.

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

On the ListBox use the Style

<ListBox    Style="{DynamicResource disabledListBoxWithScroll}" ..... />
Jobi Joy
A: 

Hi, See this link

Rahul
That solution is the same as the one by Jobi. Nothing particularly wrong with it (especially if you are going to be applying it to multiple lists), however for my purposes, handling the events was much simpler.
Matt Briggs
A: 

I used this solution, it's really easy and works perfectly:

For every "SurfaceListBoxItem item" you put in the Listbox, do this: item.IsHitTestVisible = false;

Oskar