WPF:禁用ListBox,但启用滚动

问题描述 投票:8回答:11

整个上午都在撞我的头。

基本上,我有一个列表框,我想让人们不要在长时间运行的过程中更改选择,但允许他们仍然滚动。

解:

所有答案都很好,我选择了吞咽老鼠事件,因为那是最直接的。我将PreviewMouseDown和PreviewMouseUp连接到单个事件,该事件检查了我的backgroundWorker.IsBusy,如果将事件args的IsHandled属性设置为true。

wpf listbox scrollbar
11个回答
1
投票

诀窍是不要真的禁用。禁用将锁定滚动框中的所有消息。

在长时间操作期间,使用其.ForeColor属性使列表框中的文本变灰并吞下所有鼠标单击。这将模拟禁用控件并允许滚动无阻碍。


0
投票

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

然后,而不是在ListBox上设置IsEnabled,而是使用IsEnabledWithScroll。如果启用或禁用列表框,则滚动将起作用。


0
投票

似乎有很多方法可以为这只特殊的猫提供皮肤。我发现通过在XAML中的IsHitTestVisible上设置ItemsContainerStyle,我得到了我所需要的:

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

8
投票

如果你查看ListBox的控件模板,里面有一个ScrollBar和ItemsPresenter。因此,禁用ItemsPresenter,您将轻松获得此功能。使用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上使用Style

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

2
投票

对不起已经差不多两年了,但我认为这个使用DataTrigger的解决方案更简单。 How to disable a databound ListBox item based on a property value?


2
投票

我发现在启用了自动滚动的ScrollViewer中放置一个禁用的ListBox会产生所需的效果。


1
投票

虽然它适用于Silverlight,但是这篇博文可能会帮助您朝着正确的方向前进? Silverlight No Selection ListBox and ViewBox


1
投票

我使用这个解决方案,它非常简单,工作完美:

对于你放入SurfaceListBoxItem item的每个Listbox,请执行以下操作:

item.IsHitTestVisible = false;

1
投票

这对我来说效果最好。这很简单,整个代码在XAML中,这是IMO非常整洁。

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

0
投票

另一个值得考虑的选择是禁用ListBoxItems。这可以通过设置ItemContainerStyle来完成,如下面的代码片段所示。

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

如果您不希望文本为灰色,则可以通过使用以下键向样式的资源添加画笔来指定禁用的颜色:{x:Static SystemColors.GrayTextBrushKey}。另一种解决方案是覆盖ListBoxItem控件模板。

这个问题和这个问题几乎相同:There ain't ListBox.SelectionMode=“None”, is there another way to disable selection in a listbox?和我的答案是一样的。


0
投票

我找到了一个非常简单直接的解决方案,我希望它能帮到你

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

© www.soinside.com 2019 - 2024. All rights reserved.