带列表框的 WPF ScrollViewer

2024-04-17

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

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

检查这个代码:

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

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

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

HELP!!!

Gili


好吧,就在我准备放弃并以某种方式学习如何忍受这个错误之前,我偶然发现了一篇文章(我现在似乎找不到),该文章表明 TreeView 确实支持基于像素的滚动(又名物理滚动) )而不关闭可视化。

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

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

我为 TreeViewItem 创建了一个样式,使 TreeViewItem 的外观和行为就像 ListBoxItem 一样,这实际上不是强制性的 - 但我更喜欢这样(除了基本样式存在拉伸问题,我必须通过样式来修复)。基本上我删除了 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>

现在 - 我唯一要做的就是实现多选树视图。 可能有不同的方法来实现这种行为,我采用了 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();
}

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

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

Gili

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

带列表框的 WPF ScrollViewer 的相关文章

随机推荐

  • 有没有像 Haskell 的 Threadscope 这样的 C/C++ 线程跟踪器?

    有没有像这样的免费开源工具线程范围 http research microsoft com en us projects threadscope 并且比NPTL 追踪工具 http nptltracetool sourceforge net
  • 从 SQL Server 查询 Python 中的二进制值

    我正在执行这个查询 SELECT CMDB ID FROM DB1 dbo CDMID 当我在 SSMS 18 上执行此操作时 我得到以下信息 我知道这些是十六进制值 尽管我不是该主题的专家 我需要在 python 上执行这个精确的查询 以
  • 在python中逐层打印二叉树

    我想按以下方式打印二叉树 10 6 12 5 7 11 13 我已经编写了用于插入节点的代码 但无法编写用于打印树的代码 所以请帮忙解决这个问题 我的代码是 class Node def init self data self data d
  • 让 Graphstream 只渲染发生变化的部分

    我使用以下方法创建了一个表示特定区域路线图的图表Graphstream 现在我想让蓝色节点看起来像在图表上移动 为此我在另一个线程上显示图表 并且每秒将不同的节点着色为蓝色 如下所示 public void drawGraph List
  • Git lfs(大文件存储)表示 lfs 管理的文件在 git lfs pull 后被修改

    我有一个存储库的工作副本 它使用 git lfs 来存储一些大文件 我安装了 git lfs 二进制文件 但可能没有在工作副本中运行 git lfs install 当我想在添加 lfs 文件后更新本地工作副本时 我执行以下命令 git p
  • C:scanf循环

    char buf 1024 0 send a message if status 0 while 1 printf Enter message scanf 1023 n buf fflush stdin if strcmp buf quit
  • SQL Server 图形数据库 - 使用多种边类型的最短路径

    我已经对 SQL Server GraphDB 进行了研究 但到目前为止我发现的所有人为示例仅使用单个边缘表 总是如此Person friend of gt Person 例如 就我而言 我创建了数据中心中已部署软件组件的图表 并且存在不同
  • Android - 如何在启动后启动 /sdcard 上的应用程序

    有没有一种方法可以在启动后自动启动Android应用程序 如果它位于Android应用程序上 sdcard 好吧 大概是通过BroadcastReceiver 但哪种行动是正确的呢 ACTION BOOT COMPLETED does no
  • Html.ActionLink 无法动态调度

    我的 MVC3 有问题 我正在尝试使用 Html ActionLink 为我的博客项目中的标题生成链接 在中使用常量字符串ActionLink效果很好 但如果我使用Posts Title 当前帖子模型的标题被循环 我得到这个异常 CS197
  • 如何减少flutter web应用程序的加载时间

    截至目前 我们可以将 flutter web 应用程序作为单个文件启动 该文件将立即加载 因此需要花费大量时间和带宽来加载 这并不理想 有没有办法一次只加载一个页面 而不是整个网络应用程序 我的意思是 一次加载一个小部件 任何建议将不胜感激
  • 卡夫卡高级消费者 error_code=15

    当尝试使用高级消费者 使用全新的消费者组 从 Kafka 进行消费时 消费者永远不会开始运行 当我将日志记录级别切换为调试时 我可以看到以下两行一遍又一遍地重复 DEBUG AbstractCoordinator 09 43 51 192
  • 了解跟踪*

    再会 当试图理解数学使用标准的评估顺序Trace and TraceScan最近开发的命令及其漂亮的视觉表示thread https stackoverflow com questions 5459735 the clearest way
  • foreach(... in ...) 或 .ForEach();这就是问题[重复]

    这个问题在这里已经有答案了 可能的重复 C foreach 与函数式each https stackoverflow com questions 2024305 c sharp foreach vs functional each 这是一个
  • C# 中是否有一个好的浮点数基数排序实现

    我有一个带有浮点类型字段的数据结构 这些结构的集合需要按浮点值排序 是否有一个基数排序实现 如果没有 是否有一种快速的方法来访问指数 符号和尾数 因为如果你首先对尾数 指数和最后一次的指数对浮点数进行排序 您对浮点数进行排序的时间复杂度为
  • 是否有适用于触摸移动设备的 HTML5/ jQuery 球形全景查看器

    我需要将球形全景查看器放入 Web 应用程序中 最好是 HTML5 和 jQuery 用户必须能够使用手指在全景图中移动 有谁知道有类似的东西可以使用 只需支付少量费用或更好地免费 这是一个老问题 但对于现在找到它的人 像我一样 我认为 P
  • FirebaseImageLoader 不下载图像

    我正在尝试从 ViewHolder 内部的存储中下载图像 但它不起作用 FirebaseStorage storage FirebaseStorage getInstance StorageReference storageReferenc
  • 如何使用多色热图解决 MemoryError

    我试图通过从文件中读取数据来绘制具有多种颜色的热图 我可以很好地生成 2D 和法线热图 但无法绘制如附图所示的图像 当使用随机数时 我可以绘制此图 但在从文件中读取数据时 它显示错误 上面的热图是用随机数据生成的 Input col 1 a
  • 如何更改存储在字符串中的日期格式?目标c [重复]

    这个问题在这里已经有答案了 可能的重复 如何转换 NSString 中的日期时间格式 https stackoverflow com questions 2076417 how to convert datetime format in n
  • @use 即将推出,但此版本的 Dart Sass 不支持它

    我在跑步ng serve包含 Sass 的 Angular cli 项目 我一直在使用 import and include没有问题 当我添加时 use 终端抛出 use 即将推出 但此版本的 Dart 不支持它 萨斯 我的 package
  • 带列表框的 WPF ScrollViewer

    需要你的帮助 我有一个列表框 带有虚拟化 显示一个 ScrollViewer 我的列表框项目是可展开的 展开时它们的高度可能会超出可见的滚动区域 我遇到的问题是 当列表框项目超出可见滚动区域时 滚动会跳转到下一个列表框项目 而不是简单地滚动