基于日期 Xamarin 表单过滤 ObservableCollection
Posted
技术标签:
【中文标题】基于日期 Xamarin 表单过滤 ObservableCollection【英文标题】:Filter ObservableCollection based on date Xamarin Forms 【发布时间】:2017-09-18 12:30:29 【问题描述】:第一次发帖,如有错误,请见谅。
我在根据给定日期过滤可观察集合时遇到问题。该应用程序将有一个日历,用户可以在其中单击一个日期,下面将显示该日期的约会。
有两个类,一个是从 Azure 获取数据的 dataManager,另一个是约会页面本身。
这里是约会页面类:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
using XamForms.Controls;
namespace TodoAzure
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class AppointmentPage : ContentPage
TodoItemManager manager;
CalendarVM vm = new CalendarVM();
public AppointmentPage()
InitializeComponent();
manager = TodoItemManager.DefaultManager;
calendar.DateClicked += (sender, e) =>
System.Diagnostics.Debug.WriteLine(calendar.SelectedDates);
;
calendar.SetBinding(Calendar.DateCommandProperty, nameof(vm.DateChosen));
calendar.SetBinding(Calendar.SelectedDateProperty, nameof(vm.DateSelected));
calendar.BindingContext = vm;
protected override async void OnAppearing()
base.OnAppearing();
// Set syncItems to true in order to synchronize the data on startup when running in offline mode
await RefreshItems(true, syncItems: false);
//PULL TO REFRESH
public async void OnRefresh(object sender, EventArgs e)
var list = (ListView)sender;
Exception error = null;
try
await RefreshItems(false, true);
catch (Exception ex)
error = ex;
finally
list.EndRefresh();
if (error != null)
await DisplayAlert("Refresh Error", "Couldn't refresh data (" + error.Message + ")", "OK");
public async void OnSyncItems(object sender, EventArgs e)
await RefreshItems(true, true);
private async Task RefreshItems(bool showActivityIndicator, bool syncItems)
using (var scope = new ActivityIndicatorScope(syncIndicator, showActivityIndicator))
appointmentPage.ItemsSource = await manager.GetAppointmentItemsAsync(syncItems);
private class ActivityIndicatorScope : IDisposable
private bool showIndicator;
private ActivityIndicator indicator;
private Task indicatorDelay;
public ActivityIndicatorScope(ActivityIndicator indicator, bool showIndicator)
this.indicator = indicator;
this.showIndicator = showIndicator;
if (showIndicator)
indicatorDelay = Task.Delay(2000);
SetIndicatorActivity(true);
else
indicatorDelay = Task.FromResult(0);
private void SetIndicatorActivity(bool isActive)
this.indicator.IsVisible = isActive;
this.indicator.IsRunning = isActive;
public void Dispose()
if (showIndicator)
indicatorDelay.ContinueWith(t => SetIndicatorActivity(false), TaskScheduler.FromCurrentSynchronizationContext());
这里是数据管理器类:
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.WindowsAzure.MobileServices;
using Microsoft.WindowsAzure.MobileServices.Sync;
#if OFFLINE_SYNC_ENABLED
using Microsoft.WindowsAzure.MobileServices.SQLiteStore;
using Microsoft.WindowsAzure.MobileServices.Sync;
#endif
namespace TodoAzure
public partial class TodoItemManager
static TodoItemManager defaultInstance = new TodoItemManager ();
MobileServiceClient client;
IMobileServiceTable<TodoItem> todoTable;
IMobileServiceTable<AppointmentItem> appointmentTable;
private TodoItemManager ()
this.client = new MobileServiceClient (
Constants.ApplicationURL);
this.todoTable = client.GetTable<TodoItem> ();
this.appointmentTable = client.GetTable<AppointmentItem>();
public static TodoItemManager DefaultManager
get return defaultInstance;
private set defaultInstance = value;
public MobileServiceClient CurrentClient
get return client;
public bool IsOfflineEnabled
get return appointmentTable is Microsoft.WindowsAzure.MobileServices.Sync.IMobileServiceSyncTable<AppointmentItem>;
// INSERT AND UPDATE METHODS
public async Task SaveTaskAsync (TodoItem item)
if (item.Id == null)
await todoTable.InsertAsync (item);
else
await todoTable.UpdateAsync (item);
public async Task SaveTaskAsync(AppointmentItem appointment)
if (appointment.Id == null)
await appointmentTable.InsertAsync(appointment);
else
await appointmentTable.UpdateAsync(appointment);
public async Task<ObservableCollection<AppointmentItem>> GetAppointmentItemsAsync(bool syncItems = false)
try
IEnumerable<AppointmentItem> items = await appointmentTable
.ToEnumerableAsync();
return new ObservableCollection<AppointmentItem>(items);
catch (MobileServiceInvalidOperationException msioe)
Debug.WriteLine(@"Invalid sync operation: 0", msioe.Message);
catch (Exception e)
Debug.WriteLine(@"Sync error: 0", e.Message);
return null;
任何帮助将不胜感激。
【问题讨论】:
“遇到麻烦” - 你能更具体一点吗?您是否收到错误或异常?它的行为是奇怪的,还是崩溃的?我在您的代码中没有看到任何甚至尝试进行日期过滤的逻辑? 我不确定如何使用约会页面中vm.SelectedDates
中给出的日期过滤 ObservableCollection。我尝试了其他 Stack Overflow Questions 中给出的几种方法,但都没有成功。
【参考方案1】:
要按日期过滤 IEnumerable,试试这个
// items is ObservableCollection<AppointmentItem>
var filtered = items.Where(x => x.Date == SelectedDate);
【讨论】:
它不起作用):过滤是否必须在 AppointmentPage 类中进行,因为这是用户定义 SelectedDate 的地方? 查看我的编辑 - 在我的示例中,我使用了类名而不是实例名。如果它仍然不起作用,请更具体 - 您是否在调试器中验证正在返回过滤的数据列表?至于您将过滤器表达式放在哪里,这取决于您。 我现在看到此错误“错误 CS1061 'Task以上是关于基于日期 Xamarin 表单过滤 ObservableCollection的主要内容,如果未能解决你的问题,请参考以下文章
xamarin 表单中的 datepicker 和 timepicker 多次触发 Focus 和 Unfocus 事件