2017-12-16 13 views
0

Xamarin.Formsとsqlite-net-pcl Nugetパッケージを使用して非常に単純なリスト作成アプリケーションを作成しました。私は単一のモデルListItemを持っていて、ブール値の属性はActiveです。 2つのリスト:activeItemsActive = true、およびinactiveItemsActive = false)。ユーザがactiveItemsリスト内の項目をタップすると、Active = falseに設定され、2つのリストがリロードされます。ユーザーがinactiveItemsリスト内の項目をタップすると、Active = trueに設定され、2つのリストがリロードされます。すべてこれは素晴らしい作品です。同じ非同期メソッドとは逆の同期コマンド

しかし、完全なものとしてマークするだけでなく、アイテムを完全に削除するオプションも提供したいと考えています。ユーザーがアイテムのMenuItem(いずれかのリストにある)を長時間保持して「削除」を選択すると、ListItemはデータベースから削除されますが、activeItemsリストから削除されず、inactiveItemsリストは完全に消滅しますページをリロードすると、inactiveItemsの一覧が戻って、activeItemsの一覧には、削除された項目が不足しています)。これは文字通り私の "SetActive/Inactive"メソッドを "DeleteListItem"メソッドにコピー&ペーストしたので、これは本当に奇妙です。唯一の違いは、 "DeleteListItem"は同期的ですが、なぜそれがそれが何をしているのかを理解する必要はありません。

サイドノート:それぞれの方法について、私は両方のリストのHeightRequestをリロードして、内容に正確に合致します。

誰でも問題を確認できますか?または、誰かが私の "DeleteListItem"メソッドを非同期にする方法を知っていれば、それは問題であるという機会に、素晴らしいことかもしれません。

更新

私は私の "DeleteListItem" 非同期を作ってみましたが、動作は変更されませんでした。私はApp.ListItemRepo.GetActiveListItems());の代わりにApp.ListItemRepo.GetActiveListItemsAsync());を使用しようとしました。これは動作するメソッドで使用されているメソッドなのでです。しかし、私はこのエラーを取得する:

Error CS1503 
Argument 1: cannot convert from 'System.Threading.Tasks.Task<System.Collections.Generic.List<Myapp.Models.ListItem>>' to 'System.Collections.Generic.List<Myapp.Models.ListItem>' 

XAML:

<?xml version="1.0" encoding="utf-8" ?> 
<ContentPage xmlns="..." 
      xmlns:x="..." 
      x:Class="Myapp.ListPage" 
      x:Name="ListPage"> 
    <ScrollView Orientation="Vertical"> 
    <StackLayout> 

      <!-- CURRENT ITEMS LIST --> 
     <StackLayout VerticalOptions="Fill" Orientation="Vertical" HorizontalOptions="StartAndExpand"> 
      <ListView x:Name="activeList" VerticalOptions="Start" ItemTapped="SetInactive"> 
       <ListView.ItemTemplate> 
        <DataTemplate> 
          <TextCell Text="{Binding Name}"> 
           <TextCell.ContextActions> 
            <MenuItem Command="{Binding Source={x:Reference ListPage}, Path=DeleteListItem}" 
            CommandParameter="{Binding .}" Text="delete" /> 
           </TextCell.ContextActions> 
          </TextCell> 
         </DataTemplate> 
       </ListView.ItemTemplate> 
      </ListView> 
     </StackLayout> 

     <!-- PAST ITEMS LIST --> 
     <ListView x:Name="inactiveList" VerticalOptions="Start" ItemTapped="SetActive" > 
      <ListView.ItemTemplate> 
       <DataTemplate> 
       <TextCell Text="{Binding Name}"> 
        <TextCell.ContextActions> 
         <MenuItem Command="{Binding Source={x:Reference ListPage}, Path=DeleteListItem}" 
          CommandParameter="{Binding .}" Text="delete" /> 
        </TextCell.ContextActions> 
       </TextCell> 
       </DataTemplate> 
      </ListView.ItemTemplate> 
     </ListView> 
    </StackLayout> 
    </ScrollView> 
</ContentPage> 

コードビハインド:( "App.ListItemRepo" と定義し、ListItemRepository.csで定義されたメソッドを使用しています)

using Myapp.Models; 
using System; 
using System.Collections.ObjectModel; 
using System.Linq; 
using SQLite; 
using System.Threading.Tasks; 
using System.IO; 
using Xamarin.Forms; 
using System.Diagnostics; 

namespace Myapp 
{ 
    public partial class ListPage 
    { 
     public Command DeleteListItem { get; set; } 

     public ListPage() 
     { 
      InitializeComponent(); 

      ObservableCollection<ListItem> activeItems = 
       new ObservableCollection<ListItem>(
        App.ListItemRepo.GetActiveListItems()); 
      activeList.ItemsSource = activeItems; 
      activeList.HeightRequest = 50 * activeItems.Count; 

      ObservableCollection<ListItem> inactiveItems = 
       new ObservableCollection<ListItem>(
        App.ListItemRepo.GetInactiveListItems()); 
      inactiveList.ItemsSource = inactiveItems; 
      inactiveList.HeightRequest = 50 * inactiveItems.Count; 

      }); 

      // DELETE METHOD 
      DeleteListItem = new Command((parameter) => { 
       ListItem item = (ListItem)parameter as ListItem; 

       App.ListItemRepo.DeleteListItemAsync(item); 

       ObservableCollection<ListItem> commandActiveItems = 
        new ObservableCollection<ListItem>(
         App.ListItemRepo.GetActiveListItems()); 
       activeList.ItemsSource = commandActiveItems; 
       activeList.HeightRequest = 50 * commandActiveItems.Count; 

       ObservableCollection<ListItem> commandInactiveItems = 
        new ObservableCollection<ListItem>(
         App.ListItemRepo.GetInactiveListItems()); 
       inactiveList.ItemsSource = commandInactiveItems; 
       inactiveList.HeightRequest = 50 * commandInactiveItems.Count; 
      }); 
     } 

     // SET AS ACTIVE METHOD 
     public async void SetActive(object sender, ItemTappedEventArgs e) 
     { 
      var selectedListItem = e.Item as ListItem; 
      await App.ListItemRepo.SetListItemActive(selectedListItem); 

      ObservableCollection<ListItem> activeItems = 
       new ObservableCollection<ListItem>(
        await App.ListItemRepo.GetActiveListItemsAsync()); 
      activeList.ItemsSource = activeItems; 
      activeList.HeightRequest = 50 * activeItems.Count; 

      ObservableCollection<ListItem> inactiveItems = 
       new ObservableCollection<ListItem>(
        await App.ListItemRepo.GetInactiveListItemsAsync()); 
      inactiveList.ItemsSource = inactiveItems; 
      inactiveList.HeightRequest = 50 * inactiveItems.Count; 
     } 

     // SET AS INACTIVE METHOD 
     public async void SetInactive(object sender, ItemTappedEventArgs e) 
     { 
      var selectedListItem = e.Item as ListItem; 
      await App.ListItemRepo.SetListItemInactive(selectedListItem); 

      ObservableCollection<ListItem> activeItems = 
       new ObservableCollection<ListItem>(
        await App.ListItemRepo.GetActiveListItemsAsync()); 
      activeList.ItemsSource = activeItems; 
      activeList.HeightRequest = 50 * activeItems.Count; 

      ObservableCollection<ListItem> inactiveItems = 
       new ObservableCollection<ListItem>(
        await App.ListItemRepo.GetInactiveListItemsAsync()); 
      inactiveList.ItemsSource = inactiveItems; 
      inactiveList.HeightRequest = 50 * inactiveItems.Count; 
     } 
    } 
} 

資産/ ListItemRepository.cs

using System; 
using System.Collections.Generic; 
using System.Linq; 
using Myapp.Models; 
using SQLite; 
using System.Threading.Tasks; 

namespace Myapp 
{ 
    public class ListItemRepository 
    { 
     private readonly SQLiteAsyncConnection conn; 
     private readonly SQLiteConnection syncconn; 

     public ListItemRepository(string dbPath) 
     { 
      conn = new SQLiteAsyncConnection(dbPath); 
      conn.CreateTableAsync<ListItem>().Wait(); 
      syncconn = new SQLiteConnection(dbPath); 
      syncconn.CreateTable<ListItem>(); 
     } 


     public async Task SetListItemActive(ListItem listItem) 
     { 
      ListItem item = (ListItem)listItem as ListItem; 
      var result = await conn.UpdateAsync(new ListItem { Id = item.Id, Active = true, Name = item.Name }).ConfigureAwait(continueOnCapturedContext: false); 
     } 
     public async Task SetListItemInactive(ListItem listItem) 
     { 
      ListItem item = (ListItem)listItem as ListItem; 
      var result = await conn.UpdateAsync(new ListItem { Id = item.Id, Active = false, Name = item.Name }).ConfigureAwait(continueOnCapturedContext: false); 
     } 
     public async Task DeleteListItemAsync(ListItem listItem) 
     { 
      ListItem item = (ListItem)listItem as ListItem; 
      var result = await conn.DeleteAsync(new ListItem { Id = item.Id }).ConfigureAwait(continueOnCapturedContext: false); 
     } 

     public Task<List<ListItem>> GetActiveListItemsAsync() 
     { 
      return conn.QueryAsync<ListItem>("select * from list_items where Active = 1"); 
     } 
     public Task<List<ListItem>> GetInactiveListItemsAsync() 
     { 
      return conn.QueryAsync<ListItem>("select * from list_items where Active = 0"); 
     } 

     public List<ListItem> GetActiveListItems() 
     { 
      return syncconn.Query<ListItem>("select * from list_items where Active = 1"); 
     } 
     public List<ListItem> GetInactiveListItems() 
     { 
      return syncconn.Query<ListItem>("select * from list_items where Active = 0"); 
     } 
    } 
} 

答えて

1

あなたは非同期で、あなたのコマンドを呼び出すことができます。 DeleteListItemコマンドでasyncキーワードの前に(パラメータ)を追加するだけです。次に、DeleteListItemAsyncメソッドを非同期に呼び出す必要があります。最後に、GetActiveListItemsAsyncの代わりにGetActiveListItemsAsyncを呼び出します。

 DeleteListItem = new Command(async (parameter) => { 
      ListItem item = (ListItem)parameter as ListItem; 

      await App.ListItemRepo.DeleteListItemAsync(item); 

      ObservableCollection<ListItem> commandActiveItems = 
       new ObservableCollection<ListItem>(
        await App.ListItemRepo.GetActiveListItemsAsync()); 
      activeList.ItemsSource = commandActiveItems; 
      activeList.HeightRequest = 50 * commandActiveItems.Count; 

      ObservableCollection<ListItem> commandInactiveItems = 
       new ObservableCollection<ListItem>(
        await App.ListItemRepo.GetInactiveListItemsAsync()); 
      inactiveList.ItemsSource = commandInactiveItems; 
      inactiveList.HeightRequest = 50 * commandInactiveItems.Count; 
     }); 

私はそれが助けてくれることを願っています!そうでない場合は、私に教えてください:)

+0

ありがとう!しかし、その行動は変わらなかった。これはとても奇妙です。私は 'App.ListItemRepo.GetActiveListItems'を' App.ListItemRepo 'に変更しようとしました。GetActiveListItemsAsync'は動作するメソッドで使用されているメソッドですが、このエラーが発生します: '引数1: 'System.Threading.Tasks.Task > 'を' System.Collections.Generic.List 'に設定します。私はそれをどのように救うことができるか知っていますか? –

+2

あなたはその電話を待っていますか? – Jason

+0

Jasonが示唆するように、このメソッドの呼び出しを待つ必要があります。 – Kuba

関連する問題