gpt4 book ai didi

WPF ScrollViewer 与 ListBox

转载 作者:行者123 更新时间:2023-12-04 14:21:58 24 4
gpt4 key购买 nike

需要你的帮助。我有一个显示 ScrollViewer 的 ListBox(带有 虚拟化 )。
我的 ListBox 项目是可扩展的,并且在扩展时它们的高度可能会超出可见的滚动区域。

我遇到的问题是,当列表框项目超出可见滚动区域时 - 滚动跳转到下一个 ListBox 项目,而不是简单地 ScrollView 。

检查此代码:

    <ListBox Grid.Row="1" Grid.Column="0" DataContext="{Binding SpecPackageSpecGroupListViewModel}" VirtualizingStackPanel.IsVirtualizing="True" VirtualizingStackPanel.VirtualizationMode="Recycling"
ItemContainerStyle="{StaticResource SpecPackageSpecGroupListBoxStyle}" ScrollViewer.IsDeferredScrollingEnabled="True"
ItemsSource="{Binding SortedChildren}" ScrollViewer.CanContentScroll="True"
Background="Transparent"
BorderThickness="0" SelectionMode="Extended"
Margin="5,5,5,5">
<ListBox.ItemTemplate>
<DataTemplate>
<Controls:SpecPackageSpecGroupControl/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>

当然,我不能用另一个滚动条包裹我的 ListBox,因为它会关闭可视化(这对我来说非常无能为力)。

如果我将 CanContentScroll 设置为 False 一切都按预期工作 - 但虚拟化停止工作。

帮助!!!

吉利

最佳答案

好的,所以就在我要放弃并以某种方式学习如何忍受这个错误之前,我遇到了一个帖子(我现在似乎找不到),它表明 TreeView 确实支持基于像素的滚动(又名物理滚动) 而不关闭可视化。

所以我尝试了这个,确实 - 它有效!确保验证虚拟化是否有效,使用大约 1000 个项目进行测试,并在我的控件构造函数上设置一个断点,并确保在我的 View 滚动时调用它。

使用 TreeView 而不是 ListBox 的唯一缺点是 TreeView 似乎不支持多项选择(我需要) - 但实现这一点比实现 ListBox 的智能滚动要容易得多。

我为 TreeViewItem 创建了一个样式,它使 TreeViewItem 的外观和行为就像 ListBoxItem 一样,这实际上不是强制性的 - 但我更喜欢这样(除了基本样式有拉伸(stretch)问题,我必须通过样式修复)。基本上我删除了 ItemsPresenter 并只保留了 ContentPresenter,因为我的数据不是分层的:

    <Style x:Key="MyTreeViewItemStyle" TargetType="{x:Type TreeViewItem}">
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
<Setter Property="SnapsToDevicePixels" Value="true"/>
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="VerticalContentAlignment" Value="Stretch"/>
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TreeViewItem}">
<Border Name="myBorder"
SnapsToDevicePixels="true"
CornerRadius="0,0,0,0"
VerticalAlignment="Stretch"
HorizontalAlignment="Stretch"
BorderThickness="0"
BorderBrush="Transparent"
Height="Auto"
Margin="1,1,1,3"
Background="Transparent">
<ContentPresenter Grid.Column="1" x:Name="PART_Header" HorizontalAlignment="Stretch" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" ContentSource="Header"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

现在 - 我唯一要做的就是实现多选 TreeView 。
实现这种行为可能有不同的方法,我采用了 ViewModel 方法。

派生自 TreeView 我创建了一个新的 MultiSelectionTreeView:
public class MultiSelectionTreeView : TreeView
{
private static bool CtrlPressed
{
get
{
return Keyboard.IsKeyDown(Key.LeftCtrl);
}
}

protected override void OnSelectedItemChanged(RoutedPropertyChangedEventArgs<object> e)
{
base.OnSelectedItemChanged(e);

var previouseItemViewModel = e.OldValue as IMultiSelectionTreeViewItemViewModel;
if (previouseItemViewModel != null)
{
if (!CtrlPressed)
previouseItemViewModel.IsSelected = false;
}

var newItemViewModel = e.NewValue as IMultiSelectionTreeViewItemViewModel;
if (newItemViewModel != null)
{
if (!CtrlPressed)
newItemViewModel.ClearSelectedSiblings();
newItemViewModel.IsSelected = true;
}
}
}

其中 IMultiSelectionTreeViewItemViewModel 如下:
public interface IMultiSelectionTreeViewItemViewModel
{
bool IsSelected { get; set; }
void ClearSelectedSiblings();
}

当然——现在我有责任处理所选项目的呈现方式——在我的例子中,它是因为我的 TreeView 项目有自己的 DataTemplate 来指示其选择的。
如果这不是您的情况并且您需要它,只需扩展您的 TreeView 项数据模板以根据其 View 模型 IsSelected 属性指示其选择状态。

希望有一天这会对某人有所帮助:-)
玩得开心!

吉利

关于WPF ScrollViewer 与 ListBox,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3791199/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com