当我在ListBox中插入项目时,我的屏幕也会移动

问题描述

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

因为verticalOffset相同,但是ExtraHeight放大了。

我只想在插入某些项目时不要移动scrollBar ...

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

VerticalOffSet不为0或max Height时出现症状。 您可以看到以下内容

Before Insert Item

After Insert Item

我已经手动移动了它(带代码) 但是当我将其移动到原始位置时,我应该观看移动动画。

你有个主意吗?

请让我知道这件事。

解决方法

在WPF中,ItemsControl保持相对于列表开头的滚动偏移,当将项目添加到ItemsSource时,将迫使视口中的项目向下移动。 UWP允许自定义此行为,例如表现出您所需的方式。

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

以下示例扩展了ListBox并处理了内部ScrollViewer来调整滚动偏移量,以在将项目添加到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;
  }
}

可以通过使行为可选,例如通过引入枚举来增强该类。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...