WPF列表框滚动到底部

WPF列表框滚动到底部,wpf,scroll,listbox-control,Wpf,Scroll,Listbox Control,我正在使用ObservableCollection作为我的listBox组件的ItemSource: public class MyListBox : ListBox { protected override void OnItemsChanged(System.Collections.Specialized.NotifyCollectionChangedEventArgs e) { base.OnItemsChanged(e); if (Item

我正在使用ObservableCollection作为我的listBox组件的ItemSource:

public class MyListBox : ListBox
{
    protected override void OnItemsChanged(System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
    {
        base.OnItemsChanged(e);
        if (Items.Count > 0)
        {
            var item = Items[Items.Count - 1];
            UpdateLayout();
            ScrollIntoView(item);
            UpdateLayout();
        }
    }

}
但是控制的行为对我来说是不合适的。我把这件事向下滚动到我收藏的第一件事,但不是最后一件

样本列表为:1,1,2,3,4,5,6,7,8,9,11,22,33,1

当您输入上一个1时,您可以将组件向上滚动到第一个1:)。这不是我所期待的

请告知。以下是组件代码:

public class MyListBox : ListBox
{
    protected override void OnItemsChanged(System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
    {
        base.OnItemsChanged(e);
        if (Items.Count > 0)
        {
            var item = Items[Items.Count - 1];
            UpdateLayout();
            ScrollIntoView(item);
            UpdateLayout();
        }
    }

}

抱歉,它必须是一个类作为列表,否则OC将真正进行值比较。因此,您需要使相同的值唯一。我对此进行了测试,结果很有效

     <StackPanel Orientation="Vertical" >
        <ListBox x:Name="lbStringList" ItemsSource="{Binding Path=UniqueStringList}" DisplayMemberPath="Str" Height="60" VerticalAlignment="Top"/>
        <Button Click="Button_Click" Content="56" />
     </StackPanel>


    private List<UniqueString> uniqueStringList = new List<UniqueString>() 
            {                   
                new UniqueString("zero",0),
                new UniqueString("one",1),
                new UniqueString("two",2),
                new UniqueString("three",3),
                new UniqueString("four",4),
                new UniqueString("five",5),
                new UniqueString("six",6),
                new UniqueString("seven",7),
                new UniqueString("zero",8)
            }; 

    public MainWindow()
    {
        InitializeComponent();

    }
    public List<string> StringList { get { return new List<string>() { "one", "two", "three", "four", "five", "one" }; } }
    public List<UniqueString> UniqueStringList 
    { 
        get 
        {
            return uniqueStringList;
        } 
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        System.Diagnostics.Debug.WriteLine(sender.GetHashCode());
        lbStringList.ScrollIntoView(lbStringList.Items[8]);

    }
    public class UniqueString
    {
        private Int32 id;
        public string Str { get; private set; }
        public override bool Equals(object obj)
        {
            UniqueString item = (UniqueString)obj;
            return item.id == id;
        }
        public override int GetHashCode()
        {
            return id;
        }

        public UniqueString(string str, Int32 _id) { Str = str; id = _id; }
    }

私有列表uniqueStringList=新列表()
{                   
新的唯一字符串(“零”,0),
新的唯一字符串(“一”,1),
新的唯一字符串(“2”,2),
新的唯一字符串(“三”,3),
新的唯一字符串(“四”,4),
新的唯一字符串(“五”,5),
新的唯一字符串(“六”,6),
新的唯一字符串(“七”,7),
新的唯一字符串(“零”,8)
}; 
公共主窗口()
{
初始化组件();
}
public List StringList{get{return new List(){“一”、“二”、“三”、“四”、“五”、“一”};}
公共列表UniqueStringList
{ 
得到
{
返回唯一字符串列表;
} 
}
私有无效按钮\u单击(对象发送者,路由目标e)
{
System.Diagnostics.Debug.WriteLine(sender.GetHashCode());
滚动视图(lbStringList.Items[8]);
}
公共类唯一字符串
{
私有Int32 id;
公共字符串Str{get;private set;}
公共覆盖布尔等于(对象对象对象)
{
UniqueString项=(UniqueString)obj;
return item.id==id;
}
公共覆盖int GetHashCode()
{
返回id;
}
public UniqueString(string str,Int32_id){str=str;id=_id;}
}

您是否有和可观察到的收集?如果你的最后一项是33,它能工作吗?如果是这样,那么所做的就是对列表项进行相等的比较。尝试列表,因为它的行为可能不同。如果不是,则需要绑定到一个自定义类,在该类中实现GetHashCode和overide Equals,以便th first 1不等于last 1。如果是33,则此操作很有效,因为之前的集合中没有33。我必须使用ObservableCollection来满足数据源的变化。绑定到自定义类是很遗憾的:(看起来不错。但使用dateStamp而不是int ID来避免不必要的参数也不错。问题是哈希必须是Int32。因此,如果你能传递unique Int32,你将获得更快的代码。如果你要重写Equals,我很确定你必须重写GetHashCode,但我不确定。我是那些让它运行得更快的人之一。