当我在 ListBox 中插入项目时,我的屏幕也会移动 [英] When i insert item in ListBox, my screen also move

查看:130
本文介绍了当我在 ListBox 中插入项目时,我的屏幕也会移动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

与主题相同,当我在 ListBox 中添加一些项目时,Listbox 的滚动条也会自动移动.

Same with the subject, When i add some item in ListBox, also Listbox's Scroll Bar is moved automatically.

因为verticalOffset是一样的,但是ExtraHeight被放大了.

Because verticalOffset is same, but ExtraHeight is enlarged.

我只想在插入某个项目时不要移动滚动条...

I Just want Don't move scrollBar when i insert some item...

我同时使用了 ObservableCollection 的 Insert(0, Object) 方法和 Add() 方法

I use both of ObservableCollection's Insert(0, Object) method and Add() method

当 VerticalOffSet 既不是 0 也不是 max Height 时,会出现该症状.你可以看到像下面这样

The Symptom appears when VerticalOffSet is not 0 nor max Height. You can see that like below

我已经手动移动了它(使用代码)但是当我移动它原来的位置时,我应该看移动动画.

And i already moved it manually(with Code) But when i move it original position, I should watch the move animation.

你有什么想法吗?

请了解我.

推荐答案

在 WPF 中,ItemsControl 维护相对于列表开头的滚动偏移,强制视口中的项目在出现项目时向下移动被添加到 ItemsSource.UWP 允许自定义此行为,例如以您需要的方式行事.

In WPF the ItemsControl maintains the scroll offset relative to the beginning of the list, forcing items in the viewport to move down when items are added to the ItemsSource. UWP allows to customize this behavior e.g. to behave the way you need it.

我建议扩展 ListBox 或创建附加行为.

I recommend to extend ListBox or alternatively create an attached behavior.

以下示例扩展了 ListBox 并处理内部 ScrollViewer 以调整滚动偏移以在将项目添加到 ItemsSource 时保持视口中的第一个可见项目:

The following example extends ListBox and handles the internal ScrollViewer to adjust the scroll offset to keep the first visible item in the viewport when items are added to the ItemsSource:

class KeepItemsInViewListBox : ListBox
{
  private ScrollViewer ScrollViewer { get; set; }

  #region Overrides of FrameworkElement

  /// <inheritdoc />
  public override void OnApplyTemplate()
  {
    base.OnApplyTemplate();
    if (TryFindVisualChildElement(this, out ScrollViewer scrollViewer))
    {
      this.ScrollViewer = scrollViewer;
    }
  }

  #endregion

  #region Overrides of ListView

  /// <inheritdoc />
  protected override void OnItemsChanged(NotifyCollectionChangedEventArgs e)
  {
    base.OnItemsChanged(e);

    if (this.ScrollViewer == null)
    {
      return;
    }

    double verticalOffset;
    switch (e.Action)
    {
      case NotifyCollectionChangedAction.Add when e.NewItems != null:
        // Check if insert or add
        verticalOffset = e.NewStartingIndex < this.ScrollViewer.VerticalOffset 
          ?  this.ScrollViewer.VerticalOffset + e.NewItems.Count 
          : this.ScrollViewer.VerticalOffset;
        break;
      case NotifyCollectionChangedAction.Remove when e.OldItems != null:
        verticalOffset = this.ScrollViewer.VerticalOffset - e.OldItems.Count;
        break;
      default:
        verticalOffset = this.ScrollViewer.VerticalOffset;
        break;
    }

    this.ScrollViewer?.ScrollToVerticalOffset(verticalOffset);
  }


  #endregion

  public bool TryFindVisualChildElement<TChild>(DependencyObject parent, out TChild childElement)
    where TChild : FrameworkElement
  {
    childElement = null;
    if (parent == null)
    {
      return false;
    }

    for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++)
    {
      DependencyObject child = VisualTreeHelper.GetChild(parent, i);
      if (child is TChild resultElement)
      {
        childElement = resultElement;
        return true;
      }

      if (TryFindVisualChildElement(child, out childElement))
      {
        return true;
      }
    }

    return false;
  }
}

可以通过使行为成为可选的来增强类,例如,通过引入枚举.

The class can be enhanced by making the behavior optional e.g., by introducing an enum.

这篇关于当我在 ListBox 中插入项目时,我的屏幕也会移动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆