【问题标题】:Filter ObservableCollection based on date Xamarin Forms基于日期 Xamarin 表单过滤 ObservableCollection
【发布时间】: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 中给出的几种方法,但都没有成功。

标签: c# azure xamarin filter observablecollection


【解决方案1】:

要按日期过滤 IEnumerable,试试这个

// items is ObservableCollection<AppointmentItem>
var filtered = items.Where(x => x.Date == SelectedDate);

【讨论】:

  • 它不起作用):过滤是否必须在 AppointmentPage 类中进行,因为这是用户定义 SelectedDate 的地方?
  • 查看我的编辑 - 在我的示例中,我使用了类名而不是实例名。如果它仍然不起作用,请更具体 - 您是否在调试器中验证正在返回过滤的数据列表?至于您将过滤器表达式放在哪里,这取决于您。
  • 我现在看到此错误“错误 CS1061 'Task>' 不包含 'Where' 的定义并且没有扩展方法 'Where' 接受类型为 'Task 的第一个参数>' 可以找到(您是否缺少 using 指令或程序集引用?)”。缓慢但肯定会到达那里。
  • 您需要包含“System.LINQ;”在您的 using 语句中
猜你喜欢
  • 2020-05-12
  • 2013-09-06
  • 2016-03-06
  • 1970-01-01
  • 2014-03-31
  • 1970-01-01
  • 2020-03-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多