ListView不会滚动分组

我只是将我的ListView更改为使用分组,但现在我不能再使用ScrollTo了。

我创建了一个简单的应用程序,因此您可以看到问题所在。

XAML页面看起来像(我现在不在我的应用程序中使用XAML,但我将在即将推出的版本中使用)。

             

并且示例的代码隐藏文件看起来像这样

 [XamlCompilation(XamlCompilationOptions.Compile)] public partial class ProjectPage : ContentPage { public ProjectPage() { InitializeComponent(); BindingContext = new ProjectsViewModel(); } protected override void OnAppearing() { base.OnAppearing(); Acr.UserDialogs.UserDialogs.Instance.ShowLoading(); var projects = Newtonsoft.Json.JsonConvert.DeserializeObject<IList>("[{\"ProjectName\":\"Test sag\",\"ProjectReference\":\"10072\",\"CustomerName\":\"Test firma\",\"FullAddress\":\"Testvej 3\",\"StartDate\":\"2017-02-02T00:00:00\",\"StartTime\":\"\"},{\"ProjectName\":\"aaa\",\"ProjectReference\":\"10077\",\"CustomerName\":\"Test firma\",\"FullAddress\":\"Testvej 12\",\"StartDate\":\"2017-02-08T00:00:00\",\"StartTime\":\"\"},{\"ProjectName\":\"Test\",\"ProjectReference\":\"10082\",\"CustomerName\":\"Test firma\",\"FullAddress\":\"Testvej 50\",\"StartDate\":\"2017-02-16T00:00:00\",\"StartTime\":\"\"},{\"ProjectName\":\"Test\",\"ProjectReference\":\"10085\",\"CustomerName\":\"Testvej boligselskab\",\"FullAddress\":\"Testvej 14\",\"StartDate\":\"2017-02-24T00:00:00\",\"StartTime\":\"\"},{\"ProjectName\":\"Test\",\"ProjectReference\":\"10086\",\"CustomerName\":\"Testing\",\"FullAddress\":\"Testevej 14\",\"StartDate\":\"2017-02-27T00:00:00\",\"StartTime\":\"\"},{\"ProjectName\":\"Test1\",\"ProjectReference\":\"10087\",\"CustomerName\":\"Plejecenter testlyst\",\"FullAddress\":\"Testlystvej 11\",\"StartDate\":\"2017-02-27T00:00:00\",\"StartTime\":\"\"},{\"ProjectName\":\"Test2\",\"ProjectReference\":\"10088\",\"CustomerName\":\"Charlie\",\"FullAddress\":\"Testvej 50\",\"StartDate\":\"2017-02-27T00:00:00\",\"StartTime\":\"\"},{\"ProjectName\":\"Test\",\"ProjectReference\":\"10089\",\"CustomerName\":\"Standard Debitor\",\"FullAddress\":\"[Mangler]\",\"StartDate\":\"2017-03-16T00:00:00\",\"StartTime\":\"\"},{\"ProjectName\":\"Test\",\"ProjectReference\":\"10090\",\"CustomerName\":\"Standard Debitor\",\"FullAddress\":\"[Mangler]\",\"StartDate\":\"2017-03-16T00:00:00\",\"StartTime\":\"\"},{\"ProjectName\":\"Test\",\"ProjectReference\":\"10091\",\"CustomerName\":\"Standard Debitor\",\"FullAddress\":\"[Mangler]\",\"StartDate\":\"2017-03-16T00:00:00\",\"StartTime\":\"\"},{\"ProjectName\":\"Test\",\"ProjectReference\":\"10092\",\"CustomerName\":\"Tester\",\"FullAddress\":\"Testvej 11\",\"StartDate\":\"2017-03-16T00:00:00\",\"StartTime\":\"\"},{\"ProjectName\":\"Test\",\"ProjectReference\":\"10093\",\"CustomerName\":\"Plejehjemmet test\",\"FullAddress\":\"Testvej 90\",\"StartDate\":\"2017-03-16T00:00:00\",\"StartTime\":\"\"},{\"ProjectName\":\"Test\",\"ProjectReference\":\"10094\",\"CustomerName\":\"Plejehjemmet test\",\"FullAddress\":\"Testvej 90\",\"StartDate\":\"2017-03-16T00:00:00\",\"StartTime\":\"\"}]"); var viewModel = BindingContext as ProjectsViewModel; if (viewModel != null) viewModel.OriginalProjects = projects; Acr.UserDialogs.UserDialogs.Instance.ShowLoading("Loading"); Task.Delay(5000).ContinueWith((x) => { Device.BeginInvokeOnMainThread(Acr.UserDialogs.UserDialogs.Instance.HideLoading); Search(); }); } private void Search(string inputVal = null) { var viewModel = BindingContext as ProjectsViewModel; if (viewModel != null) { var projects = viewModel.OriginalProjects.Where(p => !string.IsNullOrEmpty(inputVal) ? p.ProjectName.Contains(inputVal) : true); var orderedProjects = projects.OrderBy(p => p.StartDate); Device.BeginInvokeOnMainThread(() => { foreach (ProjectDto project in orderedProjects) { var coll = viewModel.Projects.FirstOrDefault(c => c.Key == project.StartDate); if (coll == null) viewModel.Projects.Add(coll = new ObservableCollectionWithDateKey { Key = project.StartDate }); coll.Add(project); } var group = viewModel.Projects.LastOrDefault(); if (group != null) ProjectsListView.ScrollTo(group.First(), group.Key, ScrollToPosition.Start, false); }); } } } class ProjectsViewModel : INotifyPropertyChanged { private ObservableCollection _projects; public event PropertyChangedEventHandler PropertyChanged; public IEnumerable OriginalProjects { get; set; } public ObservableCollection Projects { get { return _projects; } set { _projects = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Projects))); } } public ProjectsViewModel() { Projects = new ObservableCollection(); } } public class ProjectDto : INotifyPropertyChanged { public string ProjectName { get; set; } public string ProjectReference { get; set; } public string CustomerName { get; set; } public string FullAddress { get; set; } public DateTime StartDate { get; set; } public string StartTime { get; set; } public event PropertyChangedEventHandler PropertyChanged; } class ObservableCollectionWithDateKey : ObservableCollection { public DateTime Key { get; set; } } 

我使用Task.Delay(5000)模拟来自服务器的响应,但我不认为,这很重要。

UPDATE

我想通了,问题出在我的ScrollTo -call中,其中ScrollTo(group.First(), group.Key, ScrollToPosition.Start, false); 用Key调用而不仅仅是组。

如果首先创建分组(不将其添加到ViewModel),则必须在ViewModel中找到正确的模型。 否则找不到正确的ObservableCollection

我已经测试了您的代码并重现了您的问题。 问题是您已将错误的参数传递给ScrollTo方法。

 ProjectsListView.ScrollTo(group.First(), group.Key, ScrollToPosition.Start, false); 

ScrollTo方法的group参数是ListView.ItemsSource的组。 但是你通过了一个group.Keygroup.Key 。 所以这种方法不会像预期的那样兴奋。 请修改如下代码。

 Device.BeginInvokeOnMainThread(() => { foreach (ProjectDto project in orderedProjects) { var coll = viewModel.Projects.FirstOrDefault(c => c.Key == project.StartDate); if (coll == null) viewModel.Projects.Add(coll = new ObservableCollectionWithDateKey { Key = project.StartDate }); coll.Add(project); } var group = viewModel.Projects.Last(); if (group != null) ProjectsListView.ScrollTo(group.First(), group, ScrollToPosition.Start, false); });