ListView滚动至最后一项WPF C#
在WPF中,如何使滚动规则始终在ListView的末尾自动而无焦点 使用附加属性。本文将向您展示如何:ListView滚动至最后一项WPF C#,c#,wpf,C#,Wpf,在WPF中,如何使滚动规则始终在ListView的末尾自动而无焦点 使用附加属性。本文将向您展示如何: 你可以用这个,它对我有用: this.myListView.ScrollIntoView(myListView.Items[myListView.Items.Count-1]) 如果您需要更高级的详细信息,您可以参考此,因为@pduncan的答案不包括实际代码,以下是他们发布的链接中的代码,我只做了一点小小的修改: public class ListBoxExtenders : Depende
你可以用这个,它对我有用: this.myListView.ScrollIntoView(myListView.Items[myListView.Items.Count-1])
如果您需要更高级的详细信息,您可以参考此,因为@pduncan的答案不包括实际代码,以下是他们发布的链接中的代码,我只做了一点小小的修改:
public class ListBoxExtenders : DependencyObject
{
public static readonly DependencyProperty AutoScrollToEndProperty = DependencyProperty.RegisterAttached("AutoScrollToEnd", typeof(bool), typeof(ListBoxExtenders), new UIPropertyMetadata(default(bool), OnAutoScrollToEndChanged));
/// <summary>
/// Returns the value of the AutoScrollToEndProperty
/// </summary>
/// <param name="obj">The dependency-object whichs value should be returned</param>
/// <returns>The value of the given property</returns>
public static bool GetAutoScrollToEnd(DependencyObject obj)
{
return (bool)obj.GetValue(AutoScrollToEndProperty);
}
/// <summary>
/// Sets the value of the AutoScrollToEndProperty
/// </summary>
/// <param name="obj">The dependency-object whichs value should be set</param>
/// <param name="value">The value which should be assigned to the AutoScrollToEndProperty</param>
public static void SetAutoScrollToEnd(DependencyObject obj, bool value)
{
obj.SetValue(AutoScrollToEndProperty, value);
}
/// <summary>
/// This method will be called when the AutoScrollToEnd
/// property was changed
/// </summary>
/// <param name="s">The sender (the ListBox)</param>
/// <param name="e">Some additional information</param>
public static void OnAutoScrollToEndChanged(DependencyObject s, DependencyPropertyChangedEventArgs e)
{
var listBox = s as ListBox;
if (listBox != null)
{
var listBoxItems = listBox.Items;
var data = listBoxItems.SourceCollection as INotifyCollectionChanged;
var scrollToEndHandler = new System.Collections.Specialized.NotifyCollectionChangedEventHandler(
(s1, e1) =>
{
if (listBox.Items.Count > 0)
{
listBoxItems.MoveCurrentToLast();
listBox.ScrollIntoView(listBoxItems.CurrentItem);
}
});
if ((bool)e.NewValue)
data.CollectionChanged += scrollToEndHandler;
else
data.CollectionChanged -= scrollToEndHandler;
}
}
}
公共类ListBoxExtenders:DependencyObject
{
公共静态只读DependencyProperty AutoScrollToEndProperty=DependencyProperty.RegisterAttached(“AutoScrollToEnd”、typeof(bool)、typeof(ListBoxExtenders)、new UIPropertyMetadata(默认值(bool)、OnAutoScrollToEndChanged));
///
///返回AutoScrollToEnd属性的值
///
///应返回其值的依赖项对象
///给定属性的值
公共静态bool GetAutoScrollToEnd(DependencyObject obj)
{
返回(bool)对象GetValue(AutoScrollToEndProperty);
}
///
///设置AutoScrollToEnd属性的值
///
///应设置其值的依赖项对象
///应分配给AutoScrollToEnd属性的值
公共静态void SetAutoScrollToEnd(DependencyObject对象,布尔值)
{
对象设置值(AutoScrollToEndProperty,值);
}
///
///当自动滚动结束时,将调用此方法
///属性已更改
///
///发送者(列表框)
///一些补充资料
AutoScrollToEndChanged上的公共静态无效(DependencyObject s、DependencyPropertyChangedEventArgs e)
{
var listBox=s作为listBox;
如果(列表框!=null)
{
var listBoxItems=listBox.Items;
var data=listBoxItems.SourceCollection作为INotifyCollectionChanged;
var scrollToEndHandler=new System.Collections.Specialized.NotifyCollectionChangedEventHandler(
(s1,e1)=>
{
如果(listBox.Items.Count>0)
{
listBoxItems.MoveCurrentToLast();
ScrollingToView(listBoxItems.CurrentItem);
}
});
if((bool)e.NewValue)
data.CollectionChanged+=scrollToEndHandler;
其他的
data.CollectionChanged-=scrollToEndHandler;
}
}
}
我将其修改为使用
MoveCurrentToLast
,而不是使用listBox.Items[listBox.Items.Count-1]获取最后一项代码>。原因是(除了稍微干净一点之外)存在一种边缘情况,即如果列表中有重复项,则获取listBox.items.Count-1
,然后滚动到该项可能不会将您滚动到列表的末尾(甚至可能向相反方向滚动!)。相反,它会将您滚动到该项目的第一个实例。来自@pduncan和@MattBurland的答案都有一些问题,主要是他们无法正确注销该行为
此实现将处理程序存储在另一个附加属性中,以便您可以通过绑定打开和关闭行为
请注意,这适用于列表视图
。如果使用的是ListBox
,请将出现的ListView
更改为ListBox
public static class ListViewExtensions
{
public static readonly DependencyProperty AutoScrollToEndProperty = DependencyProperty.RegisterAttached("AutoScrollToEnd", typeof(bool), typeof(ListViewExtensions), new UIPropertyMetadata(OnAutoScrollToEndChanged));
private static readonly DependencyProperty AutoScrollToEndHandlerProperty = DependencyProperty.RegisterAttached("AutoScrollToEndHandler", typeof(NotifyCollectionChangedEventHandler), typeof(ListViewExtensions));
public static bool GetAutoScrollToEnd(DependencyObject obj) => (bool)obj.GetValue(AutoScrollToEndProperty);
public static void SetAutoScrollToEnd(DependencyObject obj, bool value) => obj.SetValue(AutoScrollToEndProperty, value);
private static void OnAutoScrollToEndChanged(DependencyObject s, DependencyPropertyChangedEventArgs e)
{
var listView = s as ListView;
if (listView == null)
return;
var source = (INotifyCollectionChanged)listView.Items.SourceCollection;
if ((bool)e.NewValue)
{
NotifyCollectionChangedEventHandler scrollToEndHandler = delegate
{
if (listView.Items.Count <= 0)
return;
listView.Items.MoveCurrentToLast();
listView.ScrollIntoView(listView.Items.CurrentItem);
};
source.CollectionChanged += scrollToEndHandler;
listView.SetValue(AutoScrollToEndHandlerProperty, scrollToEndHandler);
}
else
{
var handler = (NotifyCollectionChangedEventHandler)listView.GetValue(AutoScrollToEndHandlerProperty);
source.CollectionChanged -= handler;
}
}
}
公共静态类ListViewExtensions
{
公共静态只读DependencyProperty AutoScrollToEndProperty=DependencyProperty.RegisterAttached(“AutoScrollToEnd”、typeof(bool)、typeof(ListViewExtensions)、新UIPropertyMetadata(OnAutoScrollToEndChanged));
私有静态只读DependencyProperty AutoScrollToEndHandlerProperty=DependencyProperty.RegisterAttached(“AutoScrollToEndHandler”、typeof(NotifyCollectionChangedEventHandler)、typeof(ListViewExtensions));
公共静态bool GetAutoScrollToEnd(DependencyObject obj)=>(bool)obj.GetValue(AutoScrollToEndProperty);
公共静态void SetAutoScrollToEnd(DependencyObject对象,布尔值)=>obj.SetValue(AutoScrollToEndProperty,值);
AutoScrollToEndChanged上的私有静态无效(DependencyObject s、DependencyPropertyChangedEventArgs e)
{
var listView=s作为listView;
如果(listView==null)
返回;
var source=(INotifyCollectionChanged)listView.Items.SourceCollection;
if((bool)e.NewValue)
{
NotifyCollectionChangedEventHandler scrollToEndHandler=委托
{
如果(listView.Items.Count)对我来说,如果列表框中的每条记录都不一样,那么这些都会起作用。如果它们相同,它只会滚动到第一条匹配的记录。这是更正确的解决方案。同样令人印象深刻的是,WPF中只有37行(加上注释)就完成了一些事情。链接过时,请在答案中包含代码
<ListView local:ListViewExtensions.AutoScrollToEnd="{Binding Path=AutoScroll}">