我有问题。我使用的CollectionView可以从我的网页接收自定义ViewModel中的数据,只要它返回包含数据的JSON。一旦呼叫中的[C0
=Offset
,该网页就会打印num_of_rows
。如果发生这种情况,我将设置一个布尔值"Nothing"
。现在,每次要进行网络通话时,它都会检查HitBottomOfList = true;
。ViewModel:
HitBottomOfList == false
XAML:
public class TemplateListViewModel { public double WidthHeight { get; set; } public ICommand LoadTemplates => new Command(LoadTemplateList); public int CurrentTemplateCountReceived; public bool HitBottomOfList = false; public ObservableCollection<TemplateSource> sourceList { get; set; } public TemplateListViewModel() { CurrentTemplateCountReceived = 0; sourceList = new ObservableCollection<TemplateSource>(); var mainDisplayInfo = DeviceDisplay.MainDisplayInfo; var width = mainDisplayInfo.Width; var density = mainDisplayInfo.Density; var ScaledWidth = width / density; WidthHeight = (ScaledWidth / 2); loadingTemplates += onLoadingTemplates; LoadTemplateList(); } private event EventHandler loadingTemplates = delegate { }; private void LoadTemplateList() { loadingTemplates(this, EventArgs.Empty); } private async void onLoadingTemplates(object sender, EventArgs args) { if (HitBottomOfList == false) { List<Template> templateList = await App.RestService.GetTemplates(App.User, CurrentTemplateCountReceived); if (templateList != null) { foreach (var template in templateList) { ImageSource source = ImageSource.FromUri(new Uri("mysite.org/myapp/" + template.FileName)); TemplateSource templateSource = new TemplateSource { Id = template.Id, Source = source, WidthHeight = WidthHeight, FileName = template.FileName }; sourceList.Add(templateSource); } CurrentTemplateCountReceived = sourceList.Count; } else { HitBottomOfList = true; } } } }
最后是我做的WebCall:
<CollectionView ItemsSource="{Binding sourceList}" RemainingItemsThreshold="6" RemainingItemsThresholdReachedCommand="{Binding LoadTemplates}"> <CollectionView.ItemsLayout> <GridItemsLayout Orientation="Vertical" Span="2" /> </CollectionView.ItemsLayout> <CollectionView.ItemTemplate> <DataTemplate> <ff:CachedImage Source="{Binding Source}" VerticalOptions="Center" HorizontalOptions="Center" WidthRequest="{Binding WidthHeight}" HeightRequest="{Binding WidthHeight}"> <ff:CachedImage.GestureRecognizers> <TapGestureRecognizer Tapped="imgTemplate_Clicked" /> </ff:CachedImage.GestureRecognizers> </ff:CachedImage> </DataTemplate> </CollectionView.ItemTemplate> </CollectionView>
现在的问题是,它确实触发了
public async Task<List<Template>> GetTemplates(User user, int offset) { var postData = new List<KeyValuePair<string, string>>(); postData.Add(new KeyValuePair<string, string>("un", user.Username)); postData.Add(new KeyValuePair<string, string>("pw", user.Password)); postData.Add(new KeyValuePair<string, string>("offset", offset.ToString())); var content = new FormUrlEncodedContent(postData); var weburl = "mysite.org/myapp/get_templates.php"; List<Template> response = await PostResponseTemplates(weburl, content); return response; } public async Task<List<Template>> PostResponseTemplates(string weburl, FormUrlEncodedContent content) { var response = await client.PostAsync(weburl, content); var json = await response.Content.ReadAsStringAsync(); if (json != "Nothing") { var jObject = JObject.Parse(json); var templatePropery = jObject["Templates"] as JArray; List<Template> templateList = new List<Template>(); foreach (var property in templatePropery) { List<Template> propertyList = new List<Template>(); propertyList = JsonConvert.DeserializeObject<List<Template>>(property.ToString()); templateList.AddRange(propertyList); } var sourcePropery = (JObject)jObject["Source"]; foreach (var property in sourcePropery) { string tempplateSource = property.Value.Value<string>(); App.TemplateSource = tempplateSource; } return templateList; } else { ErrorMessage = json; return default(List<Template>); } }
它认为需要更多的数据,却又一次又一次地执行命令,而已经有一条命令可以获取新数据。这会导致该应用多次获得具有相同RemainingItemsThresholdReachedCommand="{Binding LoadTemplates}"
的新数据,因此该应用将多次在CollectionView中获得相同的数据。我希望该应用调用该网页1次,以接收更多图像,然后直接加载它,而无需再次询问新数据,因此列表中的重复项将消失。因此,当几乎触底时,我如何确保它只询问一次数据?
更新
使用@Jason的代码,以下操作出错:当代码通过
offset
时,它会触发MyHandler
,但在完成之前会跳转到LoadTemplateList();
,因此允许启动下一个命令,而无需完成另一个命令。知道如何等待方法完成吗?
使用布尔值来跟踪您是否已经在处理该事件并忽略任何新事件
handling = false;