我只是将 ListView
更改为使用分组,但现在我无法再使用 ScrollTo
。
我创建了一个简单的应用程序,因此您可以看到问题。
XAML 页面看起来像(我目前没有在我的应用程序中使用 XAML,但我会在即将推出的版本中使用)。
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:ScrollListExample"
x:Class="ScrollListExample.ProjectPage">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<ListView x:Name="ProjectsListView" HasUnevenRows="True" IsGroupingEnabled="True" ItemsSource="{Binding Projects}">
<ListView.GroupHeaderTemplate>
<DataTemplate>
<ViewCell>
<Label Text="{Binding Path=Key}" />
</ViewCell>
</DataTemplate>
</ListView.GroupHeaderTemplate>
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Grid.Row="0" LineBreakMode="TailTruncation" Text="{Binding Path=ProjectName}" />
<Label Grid.Column="0" Grid.Row="1" Text="{Binding Path=ProjectReference, StringFormat='Sag: {0}'}" />
<Label Grid.Column="0" Grid.Row="2" Text="{Binding Path=CustomerName}" />
<Label Grid.Column="0" Grid.Row="3" Text="{Binding Path=FullAddress}" />
<Label Grid.Column="1" Grid.Row="0" Text="{Binding Path=StartTime}" />
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
</ContentPage>
示例的代码隐藏文件如下所示
[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<ProjectDto>>("[{\"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<ObservableCollectionWithDateKey> _projects;
public event PropertyChangedEventHandler PropertyChanged;
public IEnumerable<ProjectDto> OriginalProjects { get; set; }
public ObservableCollection<ObservableCollectionWithDateKey> Projects
{
get { return _projects; }
set
{
_projects = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Projects)));
}
}
public ProjectsViewModel()
{
Projects = new ObservableCollection<ObservableCollectionWithDateKey>();
}
}
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<ProjectDto>
{
public DateTime Key { get; set; }
}
我使用Task.Delay(5000)
来模拟来自服务器的响应,但我认为这并不重要。
更新
我发现问题出在我的 ScrollTo
调用中,其中 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.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);
});
关于c# - ListView 不随分组滚动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42979878/