2015-06-04 2 views
0

Я использую IMobileServiceTable в классе уровня доступа к данным и привязываю его к списку. Начальная загрузка работает нормально, но фильтрация не выполняется. Он всегда возвращает исходные загруженные данные.Xamarin IMobileServiceTable Not Filtering

public class ItemsManager { 

    IMobileServiceTable<Item> itemTable; 

    public ItemsManager (IMobileServiceTable<Item> todoTable) 
    { 
     this.itemTable = todoTable; 
    } 


    public async Task<List<Item>> GetTasksAsync (string searchString) 
    { 
//following doesn't work 
      var list = new List<Item> (await itemTable.Where(x => x.ItemID.Contains(searchString)).ToListAsync()); 
      return list; 

    } 

    public async Task<List<Item>> GetTasksAsync() 
    { 
      return new List<Item> (await itemTable.OrderBy(a =>a.ItemID).ToListAsync()); 

    } 

} 

Если это имеет значение, следующее мой код страницы:

public partial class ItemsListXaml : ContentPage 
{ 
    IMobileServiceTable<Item> itemTable; 
    ItemsManager itemManager; 

    public ItemsListXaml() 
    { 

     InitializeComponent(); 
     itemTable = App.client.GetTable<Item>(); 
     itemManager = new ItemsManager(itemTable); 

     App.SetItemsManager (itemManager); 
    } 

    protected async override void OnAppearing() 
    { 
     base.OnAppearing(); 
     listView.ItemsSource = await itemManager.GetTasksAsync(); 
    } 

    async void OnValueChanged (object sender, TextChangedEventArgs e) { 
     var t = e.NewTextValue; 
     // perform search on min 3 keypress 
     if (t.Length>3) { 
      listView.ItemsSource = await itemManager.GetTasksAsync(SearchFor.Text); 
     } 
    } 
} 
+0

ли OnValueChanged функции существа срабатывает вообще? –

+0

@ChrisAnderson, да, это срабатывает. –

ответ

1

Похоже, что проблема заключается в следующем:

var list = new List (await 
    itemTable.Where(x => x.ItemID.Contains searchString)).ToListAsync()); 

Не уверен, что именно то, что там происходит, но я удалось добиться чего-то подобного. В образце, который я использовал, используется прокси-объект для сохранения на выборках Azure. Я получаю один раз, чтобы получить начальный список задач и сохранить его в локальном объекте ObservableCollection, который я могу привязать к списку. Затем я могу отфильтровать объект коллекции, привязанный к списку (образец here).

У вас могут быть законные причины для получения отфильтрованного списка от Azure. На мой взгляд - и нести меня, потому что я не эксперт в дизайне приложений - если не существует значительного промежутка времени между первоначальной выборкой списка и действием фильтра, где могут появляться новые данные, введенные в таблицу, просто фильтрация локального объекта будет работать лучше и будет дешевле. Приложение всегда может обрабатывать push-уведомления для обновления списка по мере необходимости.

В основном, тянуть объекты из лазури в него, как показано здесь:

public async Task<ObservableCollection<ToDoItem>> GetTasksAsync() 
{ 
    try 
    { 
     return new ObservableCollection<ToDoItem>(await _todoTable.ReadAsync()); 
    } 
    catch (MobileServiceInvalidOperationException msioe) 
    { 
     Debug.WriteLine(@"INVALID {0}", msioe.Message); 
    } 
    catch (Exception e) 
    { 
     Debug.WriteLine(@"ERROR {0}", e.Message); 
    } 
    return null; 
} 

Затем привязать к списку, как показано здесь:

protected async override void OnAppearing() 
{ 
    base.OnAppearing(); 

    App.TodoManager.TodoViewModel.TodoItems = await App.TodoManager.GetTasksAsync(); 

    listViewTasks.ItemsSource = App.TodoManager.TodoViewModel.TodoItems; 
} 

В этом примере «App.TodoManager.TodoViewModel. TodoItems "- это полный путь к прокси-объекту, который является ObservableCollection.

Затем вы можете отфильтровать прокси-объект и переустановить его в список. Я фактически не реализовал эту часть в образце, но я снял ее копию, а затем добавил код и, похоже, работает нормально. Это было бы код:

Получения отфильтрованного списка:

public ObservableCollection<ToDoItem> GetFilteredList(string searchString) 
{ 
    return new ObservableCollection<ToDoItem> 
    (TodoViewModel.TodoItems.Where(x => x.Name.Contains(searchString))); 
} 

Вызова вспомогательного метода и привязку к ListView (Включая это в один из ваших примеров блоков):

async void OnValueChanged (object sender, TextChangedEventArgs e) { 
    var t = e.NewTextValue; 
    // perform search on min 3 keypress 
    if (t.Length>3) { 
     App.TodoManager.TodoViewModel.TodoItems = App.TodoManager.GetFilteredList(searchFor.Text); 
     listViewTasks.ItemsSource = App.TodoManager.TodoViewModel.TodoItems; 
    } 
}