ListView不滚动与分组 [英] ListView is not scrolling with grouping
问题描述
我只是将ListView
更改为使用分组,但是现在我再也不能使用ScrollTo
.
I simply changed my ListView
to use grouping, but now I can't use ScrollTo
anymore.
我已经创建了一个简单的应用程序,因此您可以看到问题.
I have create a simple app, so you can see the problem.
XAML页面看起来像(目前我不在我的应用程序中使用XAML,但我将在即将发布的版本中使用它.)
The XAML-page looks like (I am not using XAML in my app at the moment, but I will in an upcoming version).
<?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>
该示例的代码隐藏文件如下所示:
And the code-behind file for the example looks like this
[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)
模拟来自服务器的响应,但我认为这并不重要.
I use Task.Delay(5000)
to simulate a response from the server, but I do not think, it matters.
更新
我发现,问题出在我的ScrollTo
通话中,其中ScrollTo(group.First(), group.Key, ScrollToPosition.Start, false);
是用Key而不是仅使用组来调用的.
I figured out, the problem was in my ScrollTo
-call, where ScrollTo(group.First(), group.Key, ScrollToPosition.Start, false);
was called with the Key instead of just the group.
如果首先创建分组(而不将其添加到ViewModel),则必须在随后的ViewModel中找到正确的模型.因为否则找不到正确的ObservableCollection
If you create the grouping first (without adding it to the ViewModel), you have to find the correct model in the ViewModel afterwards. As it otherwise does not find the correct ObservableCollection
推荐答案
我已经测试了您的代码并重现了您的问题.问题是您将错误的参数传递给
I have tested your code and reproduced your issue. The problem is you have passed the wrong parameter to ScrollTo
method.
ProjectsListView.ScrollTo(group.First(), group.Key, ScrollToPosition.Start, false);
ScrollTo
方法的group
参数是ListView.ItemsSource
中的组.但是您通过了group.Key
.因此,该方法不会像预期的那样令人兴奋.请按如下所示修改代码.
The group
parameter of ScrollTo
method is the group from your ListView.ItemsSource
. But your passed a group.Key
. So the method will not be excited as expect. Please modify the code like following.
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);
});
这篇关于ListView不滚动与分组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!