整个早上都在敲我的头。
基本上,我有一个列表框,我想防止人们在长时间运行的过程中更改选择,但允许他们仍然滚动。
解决方案:
所有的答案都很好,我选择了吞下鼠标事件,因为那是最直接的。我将 PreviewMouseDown 和 PreviewMouseUp 连接到一个事件,该事件检查了我的 backgroundWorker.IsBusy,以及是否将事件 args 上的 IsHandled 属性设置为 true。
如果查看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}" ..... />
抱歉已经快两年了,但我认为这个使用DataTrigger的解决方案更简单。如何根据属性值禁用数据绑定的 ListBox 项?
我发现将禁用的 ListBox 放入启用自动滚动的 ScrollViewer 会产生所需的效果。
虽然它适用于 Silverlight,但也许这篇博文会帮助您朝着正确的方向前进?Silverlight 无选择列表框和视图框
诀窍是不要真正禁用。禁用将锁定滚动框中的所有消息。
在长时间操作期间,使用其 .ForeColor 属性将列表框中的文本变灰并吞下所有鼠标单击。这将模拟禁用控件并允许滚动畅通无阻。
我使用了这个解决方案,它真的很简单而且效果很好:
对于SurfaceListBoxItem item
您放入的每一个Listbox
,请执行以下操作:
item.IsHitTestVisible = false;
这对我来说效果最好。这很容易,整个代码都在 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>
另一个值得考虑的选项是禁用 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 控件模板。
这个问题与这个问题几乎相同:没有ListBox.SelectionMode =“None”,是否有另一种方法可以禁用列表框中的选择?我的答案是一样的。
我找到了一个对我有用的非常简单直接的解决方案,我希望它也对你有用
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="Focusable" Value="False"/>
</Style>
使用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。如果启用或禁用列表框,滚动将起作用。
似乎有很多方法可以给这只猫剥皮。我发现通过在 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>
好吧,我找到了一种提供此功能的好方法。我所做的是,在 listBox 的 DataTemplate 中,我使用 Page 作为 Source 将父布局启用属性与布尔标志绑定在一起。
第 1 步- 为页面提供x:Name属性。如果您使用的页面是用基页扩展的,那么请确保基页不是抽象类并且具有不带任何参数的默认构造函数。
<Page x:Class="OPMS.Views.Registration"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
x:Name="MainPage"
d:DesignWidth="1024"
Title="Registration"
>
第 2 步- 将页面用作 DataTemplate 父布局项 IsEnabled 属性的源
<ListBox Grid.Row="2"
ItemsSource="{Binding TestGroups}"
AlternationCount="2"
Padding="0"
Margin="10,5,10,10"
>
<ListBox.ItemTemplate>
<DataTemplate>
<CheckBox Content="{Binding Name}"
IsChecked="{Binding IsSelected}"
IsEnabled="{Binding Source={x:Reference MainPage}, Path=DataContext.BindingVariableHere}"
/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>