WPF: отключить ListBox, но включить прокрутку - PullRequest
8 голосов
/ 09 февраля 2009

Стучал мне по голове все это утро.

По сути, у меня есть список, и я хочу, чтобы люди не могли изменить выбор во время длительного процесса, но разрешить им продолжать прокрутку.

Решение:

Все ответы были хорошими, я пошел с глотанием событий мыши, так как это было самым прямым. Я связал PreviewMouseDown и PreviewMouseUp с одним событием, которое проверило мой backgroundWorker.IsBusy и установило ли свойство IsHandled для аргументов события значение true.

Ответы [ 11 ]

8 голосов
/ 09 февраля 2009

Если вы загляните в шаблон элемента управления ListBox, внутри будут ScrollBar и ItemsPresenter. Так что сделайте ItemsPresenter Disabled и вы получите это легко. Используйте нижеприведенный стиль в ListBox, и все готово.

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

В ListBox используйте стиль

<ListBox    Style="{DynamicResource disabledListBoxWithScroll}" ..... />
2 голосов
/ 26 февраля 2013

Я обнаружил, что помещение отключенного ListBox в ScrollViewer с включенной автоматической прокруткой дает желаемый эффект.

2 голосов
/ 14 декабря 2010

извините, прошло уже почти два года, но я думаю, что это решение, использующее DataTrigger, еще проще. Как отключить элемент ListBox с привязкой к данным на основе значения свойства?

1 голос
/ 04 апреля 2019

Это сработало лучше для меня. Это просто, и весь код написан на XAML, и это очень аккуратно.

<ListBox ItemsSource="{Binding MySource}">
  <ListBox.ItemContainerStyle>
    <Style TargetType="ListBoxItem">
      <Style.Triggers>
        <DataTrigger Binding="{Binding IsEditing}" Value="True">
          <Setter Property="IsEnabled" Value="True"/>
        </DataTrigger>
        <DataTrigger Binding="{Binding IsEditing}" Value="False">
          <Setter Property="IsEnabled" Value="False"/>
        </DataTrigger>
      </Style.Triggers>
    </Style>
  </ListBox.ItemContainerStyle>  
</ListBox>
1 голос
/ 09 июня 2010

Я использовал это решение, оно действительно простое и отлично работает:

Для каждого SurfaceListBoxItem item, который вы вводите в Listbox, сделайте следующее:

item.IsHitTestVisible = false;
1 голос
/ 09 февраля 2009

Хитрость в том, чтобы на самом деле не отключать. Отключение заблокирует все сообщения из поля прокрутки.

Во время длительной операции выделите текст в поле списка серым цветом, используя его свойство .ForeColor, и проглотите все щелчки мышью. Это симулирует отключение элемента управления и позволяет беспрепятственную прокрутку.

1 голос
/ 09 февраля 2009

Хотя это для Silverlight, может быть, этот пост в блоге поможет вам двигаться в правильном направлении? Silverlight Без выбора ListBox и ViewBox

0 голосов
/ 05 октября 2017

Кажется, есть много способов снять кожу с этой конкретной кошки. Я обнаружил, что установив IsHitTestVisible на ItemsContainerStyle в XAML, я получил именно то, что мне нужно:

<ListBox IsHitTestVisible="true" ScrollViewer.VerticalScrollBarVisibility="Auto" ScrollViewer.CanContentScroll="True">
    <ListBox.ItemContainerStyle>
        <Style TargetType="ListBoxItem">
            <Setter Property="IsHitTestVisible" Value="False" />
        </Style>
    </ListBox.ItemContainerStyle>
</ListBox>
0 голосов
/ 08 марта 2016

Полный ответ, используя http://www.codeproject.com/Tips/60619/Scrollable-Disabled-ListBox-in-WPF

Стиль:

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

Класс

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

Затем вместо установки IsEnabled в ListBox используйте вместо этого IsEnabledWithScroll Прокрутка будет работать, если список включен или отключен.

0 голосов
/ 17 января 2012

Я нашел очень простое и понятное решение, работающее на меня, надеюсь, оно подойдет и вам

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

...