当我在 ListBox 中插入项目时,我的屏幕也会移动
When i insert item in ListBox, my screen also move
同题,当我在ListBox中添加一些项目时,Listbox的滚动条也会自动移动。
因为verticalOffset是一样的,只是ExtraHeight变大了
我只想插入一些项目时不要移动滚动条...
我同时使用了 ObservableCollection 的 Insert(0, Object) 方法和 Add() 方法
当 VerticalOffSet 不为 0 或最大高度时出现此症状。
你可以看到像下面这样
→
而且我已经手动移动了它(使用代码)
但是当我移动它原来的位置时,我应该看移动动画。
你有想法吗?
请了解我。
在 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;
}
}
class 可以通过使行为可选,例如通过引入枚举来增强。
同题,当我在ListBox中添加一些项目时,Listbox的滚动条也会自动移动。
因为verticalOffset是一样的,只是ExtraHeight变大了
我只想插入一些项目时不要移动滚动条...
我同时使用了 ObservableCollection 的 Insert(0, Object) 方法和 Add() 方法
当 VerticalOffSet 不为 0 或最大高度时出现此症状。 你可以看到像下面这样
而且我已经手动移动了它(使用代码) 但是当我移动它原来的位置时,我应该看移动动画。
你有想法吗?
请了解我。
在 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;
}
}
class 可以通过使行为可选,例如通过引入枚举来增强。