繁体   English   中英

WPF StackPanel“跳转”

[英]WPF StackPanel “Jumps”

我有一个包含文本框和组合框的StackPanel。

当我将焦点设置在文本框(而不是第一个文本框)中时,StackPanel的内容“跳转”并转到顶部。

下面是代码。 我已经对此进行了研究,并发布了我找到并尝试过的结果(但没有发现)。

我想防止“跳跃”。

因此,运行下面的代码。 滚动垂直栏,直到看到:

Name Three       <<Text Box
(No Selection) ComboBox \/
Name Four      <<Text Box
(No Selection) ComboBox \/

现在,将光标置于“名称四”文本框中....,然后将其“跳转”到顶部。 (您现在看不到三个和四个,看到四个和五个。)

在现实生活中,我的堆栈面板要比这复杂得多,这推动了最终用户的精力充沛。

谢谢。

MainWindow.xaml

<Window x:Class="ListBoxControlSample.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="160" Width="250">
    <Grid Margin="10">
        <ListBox ItemsSource="{Binding Models}" SelectionMode="Single" RequestBringIntoView="FrameworkElement_OnRequestBringIntoView" SelectionChanged="Selector_OnSelectionChanged" >
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel>
                        <TextBox Text="{Binding Name}"/>
                        <ComboBox VerticalContentAlignment="Top" VerticalAlignment="Top" Grid.Column="1" ItemsSource="{Binding Options}" >
                        </ComboBox>
                        <TextBlock Text="{Binding Title}"></TextBlock>
                    </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
    </Grid>
</Window>

MainWindow.xaml.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace ListBoxControlSample
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            DataContext = this;
        }

        private IList<Model> _models;
        public IList<Model> Models
        {
            get
            {
                return _models ?? (_models = new List<Model>
                    {
                        new Model{ Name = "Name One", Title = "Title One"},
                        new Model{ Name = "Name Two", Title = "Title Two"},
                        new Model{ Name = "Name Three", Title = "Title Three"},
                        new Model{ Name = "Name Four", Title = "Title Four"},
                        new Model{ Name = "Name Five", Title = "Title Five"},
                        new Model{ Name = "Name Six", Title = "Title Six"},
                        new Model{ Name = "Name Seven", Title = "Title Seven"}
                    });
            }
        }

        private void FrameworkElement_OnRequestBringIntoView(object sender, RequestBringIntoViewEventArgs e)
        {
            e.Handled = true;
        }

        private void Selector_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            //throw new NotImplementedException();
        }

        private void Selector_OnSelected(object sender, RoutedEventArgs e)
        {
            //throw new NotImplementedException();
        }
    }

    public class Model
    {
        public string Name { get; set; }
        public string Title { get; set; }
        private IList<string> _options;
        public IList<string> Options
        {
            get
            {
                return _options ?? (_options = new List<string>
                    {
                        "left",
                        "right",
                        "both"
                    });
            }
        }
    }
}

我发现并尝试过的内容(以防止跳跃)

        <DataTemplate>
                    <StackPanel ScrollViewer.CanContentScroll="False">

我猜想这与默认滚动行为有关,默认滚动行为是试图在选中时显示完整项目。

尝试禁用滚动,然后将其包装在另一个ScrollViewer中:

<ScrollViewer VerticalScrollBarVisibility="Auto" CanContentScroll="True" Height="250">
    <ListBox ScrollViewer.VerticalScrollBarVisibility="Disabled">
        ...
    </ListBox>
</ScrollViewer>

这样,它不会尝试一次将每个StackPanel滚动到视图中并确保整个项目可见,而是尝试将整个ListBox滚动到视图中,这超出了分配给ScrollViewer的高度,因此它将使用所需的基于内容的滚动更流畅。

应该注意的是,这将立即渲染整个ListBox ,而不进行任何虚拟化,因此,如果您有很多行并且依赖于虚拟化来提高性能,则不建议使用此方法。 但是根据您的问题,听起来不是您的情况。

我也不是很肯定,但是您可能还必须将其嵌套在另一个面板中,以使ListBox可以增长到所需的高度。 如果需要,请参阅此答案以获取更多详细信息。

这是另一个答案。 它与简单的WPF一起使用。

但是,我的实际情况是Infragistics控制的,Rachel的答案起作用了。

但是,为了完整起见,我想发布此内容。

我要从以下网址粘贴代码:

http://social.msdn.microsoft.com/Forums/vstudio/en-US/a3532b1f-d76e-4955-b3da-84c98d6d435c/annoying-auto-scroll-of-partially-displayed-items-in-wpf-listbox?论坛= WPF

这是代码:

  <ListBox.ItemContainerStyle>
            <Style TargetType="ListBoxItem">
                <EventSetter Event="RequestBringIntoView" Handler="ListBoxItem_RequestBringIntoView"/>
            </Style>
        </ListBox.ItemContainerStyle>

  void ListBoxItem_RequestBringIntoView(object sender, RequestBringIntoViewEventArgs e)
        {
            e.Handled = true;
        }

如果您单击到最后一个可见行的文本框,效果是可重现的。 如果该行没有完全滚动到视图中,则列表框会自动将该行滚动到视图中以使其完全可见。 这又意味着所有行向上滚动一行,使您感受到跳跃的效果。 据我所知,您无法改变这种行为。

当类似SetFocus的命令在scrollviewer的子级上运行时,它会在scrrollviewer上触发ReqestBringInto视图,但是滚动到子控件的动作是由scrollviewer的ScrollInfo对象在幕后实现的。

我认为这里的关键是创建一个实现IScrollInfo的类。 我实现了一个方法来覆盖使用鼠标滚轮时SV滚动的数量。 就我而言,我从.NET源中为ScrollContentProvider克隆了默认实现,并更改了一些属性。

在内部,ScrollViewer将在所需的子控件上调用IScrollInfo :: MakeVisible()。 您可以忽略该请求。

使用以下类似方法为scrollviewer创建您自己的滚动提供程序的实例:

var myProvider = new MyScrollInfo();
myScrollViewer.ScrollInfo = myProvider;

用这个:

<ListBox ScrollViewer.PanningMode="None">

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM