【问题标题】:ListBox Scrollviewer Weird behaviorListBox Scrollviewer 奇怪的行为
【发布时间】:2013-11-18 10:07:00
【问题描述】:

我的 ListBox 的 ControlTemplate 中有 ScrollViewer,我正在使用 .Net 4.0 我在 CanContentScroll 的不同值上面临两个问题。

  1. 当 CanContentScroll 为 True 时。

    在这种情况下,当我用鼠标滚动 ListBox 时,ScrollViewer 似乎会随机跳过视图中的 1 或 2 个项目。但 SelectedItem 的选择工作正常。

  2. 当 CanContentScroll 为 False 时。

    在这种情况下,使用鼠标滚动可以正常工作。但是现在 SelectedItem 的选择并没有选择实际的 SelectedItem,而是选择它上面或下面的项目。或继续显示之前的 SelectedItem。

请帮帮我。

<Style TargetType="ListBox" x:Key="ListBoxStyle">
        <Setter Property="ItemContainerStyle" Value="{StaticResource ItemContainerStyle}"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="ListBox">
                    <ScrollViewer CanContentScroll="True">
                        <ItemsPresenter/>
                    </ScrollViewer>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

ItemContainerSTyle:

<Style x:Key="ItemContainerStyle" BasedOn="{StaticResource listBoxItemStyle}" TargetType="ListBoxItem">
        <Setter Property="helper:FluidSelectionAttachedPropertyHelper.IgnoreRightClick" Value="True"/>
        <Style.Triggers>
            <Trigger Property="IsSelected" Value="True">
                <Setter Property="Visibility" Value="Collapsed" />
            </Trigger >
        </Style.Triggers>
    </Style>

项目模板:

<Style TargetType="ListBoxItem" x:Key="listBoxItemStyle">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="ListBoxItem">
                    <ContentPresenter Margin="2"/>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

【问题讨论】:

  • 您有任何代码/xaml 与我们分享。接口很难调试。
  • 我添加了我正在使用的样式。
  • 添加您的 itemcontainer 样式和 ListBoxItem 模板和 ListBox.ItemTemplate 如果存在。

标签: wpf xaml scrollviewer


【解决方案1】:

你描述的奇怪行为正是你要求使用你的奇怪ItemContainerStyle

<Style x:Key="ItemContainerStyle" BasedOn="{StaticResource listBoxItemStyle}" 
    TargetType="ListBoxItem">
    <Style.Triggers>
        <Trigger Property="IsSelected" Value="True">
            <Setter Property="Visibility" Value="Collapsed" />
        </Trigger >
    </Style.Triggers>
</Style>

在这里,您将项目设置为在被选中时消失。

对于您的其他滚动问题,我建议您阅读 MSDN 上的 ScrollViewer.CanContentScroll Property 页面,因为我认为它似乎工作得很好:

ScrollViewer 的默认行为是使用物理单位来滚动其内容。但是,在 CanContentScroll 设置为 true 的情况下,内容可以使用逻辑单元进行滚动。

应注意,如果项目仅基于 string,则很难发现这两个设置之间的差异。

【讨论】:

  • 我也试过 Visibility=Hidden。但没有用。 SelectedItem 仍未正确选择。
  • 当然你不能选择隐藏或折叠的选中项。你为什么要隐藏选定的项目?完全摆脱ItemContainerStyle,它会选择就好了。
  • 其实我的要求是 SelectedItem 不应该出现在列表框中,因为它将被添加到购物车中。所以我会根据需要将它从列表框中隐藏起来。
  • 嗯,这不是您将如何实现... BindListBox.SelectedItem 属性以及当用户选择一个项目并且该属性在您的代码中更改时, 然后您可以从集合中删除该项目。这是 WPF...我们操作的是 数据,而不是 UI 元素
【解决方案2】:

感谢所有回复。 我找到了改变滚动查看器的垂直滚动速度保持 CanContentScroll 为 True 的解决方案。

我使用附加属性到我的滚动查看器列表框模板并使用以下处理程序方法覆盖其 PreviewMouseWheel 事件:

static void scrollViewer_MouseWheel(object sender, System.Windows.Input.MouseWheelEventArgs e)
        {
            var scrollViewer = sender as ScrollViewer;
            if (scrollViewer != null)
            {
                var newOffset = scrollViewer.VerticalOffset;
                if (newOffset < 0 || scrollViewer.ViewportHeight >= scrollViewer.ExtentHeight)
                {
                    newOffset = 0;
                    scrollViewer.ScrollToVerticalOffset(newOffset);
                }
                else if (newOffset + scrollViewer.ViewportHeight >= scrollViewer.ExtentHeight)
                {
                    newOffset = scrollViewer.ExtentHeight - scrollViewer.ViewportHeight;
                    if (e.Delta > 0)
                    {
                        scrollViewer.ScrollToVerticalOffset(newOffset - 1);
                    }
                }
                else
                {
                    if (e.Delta > 0)
                    {
                        scrollViewer.ScrollToVerticalOffset(newOffset - 1);
                    }
                    else
                    {
                        scrollViewer.ScrollToVerticalOffset(newOffset + 1);
                    }

                }
                e.Handled = true;
            }
        }

【讨论】:

    猜你喜欢
    • 2011-11-30
    • 1970-01-01
    • 2011-05-18
    • 1970-01-01
    • 1970-01-01
    • 2011-04-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多