Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
ListView滚动至最后一项WPF C#_C#_Wpf - Fatal编程技术网

ListView滚动至最后一项WPF C#

ListView滚动至最后一项WPF C#,c#,wpf,C#,Wpf,在WPF中,如何使滚动规则始终在ListView的末尾自动而无焦点 使用附加属性。本文将向您展示如何: 你可以用这个,它对我有用: this.myListView.ScrollIntoView(myListView.Items[myListView.Items.Count-1]) 如果您需要更高级的详细信息,您可以参考此,因为@pduncan的答案不包括实际代码,以下是他们发布的链接中的代码,我只做了一点小小的修改: public class ListBoxExtenders : Depende

在WPF中,如何使滚动规则始终在ListView的末尾自动而无焦点

使用附加属性。本文将向您展示如何:

你可以用这个,它对我有用:

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}">