代码之家  ›  专栏  ›  技术社区  ›  Matt Briggs

wpf:禁用列表框,但启用滚动

  •  8
  • Matt Briggs  · 技术社区  · 16 年前

    整个早上都在用头撞这个。

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

    解决方案:

    所有的答案都很好,我吞下了老鼠事件,因为那是最直接的。我将PreviewMouseDown和PreviewMouseUp连接到单个事件,该事件检查了我的backgroundWorker.isBusy,如果它被设置为true,那么事件参数上的ishandled属性也会被设置为true。

    10 回复  |  直到 16 年前
        1
  •  1
  •   Yes - that Jake.    16 年前

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

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

        2
  •  8
  •   Jobi Joy    16 年前

    如果您查看列表框的控件模板,则其中有一个滚动条和itemspresenter。因此,禁用itemspresenter,您将很容易得到它。在列表框中使用下面的样式,你就可以走了。

        <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="{DynamicResource disabledListBoxWithScroll}" ..... />
    
        3
  •  2
  •   Community CDub    7 年前

    抱歉,已经快两年了,但我认为使用DataTrigger的解决方案更简单。 How to disable a databound ListBox item based on a property value?

        4
  •  2
  •   Konrad    12 年前

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

        5
  •  1
  •   Andy    16 年前

    虽然它是为Silverlight,也许这篇博客文章会帮助你朝正确的方向发展? Silverlight No Selection ListBox and ViewBox

        6
  •  1
  •   NoNaMe    12 年前

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

    对于每一个 SurfaceListBoxItem item 你放进去 Listbox 这样做:

    item.IsHitTestVisible = false;
    
        7
  •  0
  •   Community CDub    7 年前

    另一个值得考虑的选项是禁用ListBoxItem。这可以通过如下代码段所示设置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? 我的答案是一样的。

        8
  •  0
  •   Asad Durrani    13 年前

    我发现了一个非常简单和直截了当的解决方案,我希望它也会对你有帮助。

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

        9
  •  0
  •   Chris Klepeis    9 年前

    完整答案使用 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));
    }
    

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

        10
  •  0
  •   Mageician    7 年前

    似乎有很多方法可以剥下这只特别的猫的皮。我是通过设置发现的 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>