TodoList.xaml.cs 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. using System;
  2. using System.Threading.Tasks;
  3. using Xamarin.Forms;
  4. namespace DevDaysTasks
  5. {
  6. public partial class TodoList : ContentPage
  7. {
  8. TodoItemManager manager;
  9. public TodoList()
  10. {
  11. InitializeComponent();
  12. manager = TodoItemManager.DefaultManager;
  13. }
  14. protected override async void OnAppearing()
  15. {
  16. base.OnAppearing();
  17. // Set syncItems to true in order to synchronize the data on startup when running in offline mode
  18. await RefreshItems(true, syncItems: false);
  19. }
  20. // Data methods
  21. async Task AddItem(TodoItem item)
  22. {
  23. await manager.SaveTaskAsync(item);
  24. todoList.ItemsSource = await manager.GetTodoItemsAsync();
  25. }
  26. async Task CompleteItem(TodoItem item)
  27. {
  28. item.Done = true;
  29. await manager.SaveTaskAsync(item);
  30. todoList.ItemsSource = await manager.GetTodoItemsAsync();
  31. }
  32. public async void OnAdd(object sender, EventArgs e)
  33. {
  34. var todo = new TodoItem { Name = newItemName.Text };
  35. await AddItem(todo);
  36. newItemName.Text = string.Empty;
  37. newItemName.Unfocus();
  38. }
  39. // Event handlers
  40. public async void OnSelected(object sender, SelectedItemChangedEventArgs e)
  41. {
  42. var todo = e.SelectedItem as TodoItem;
  43. if (Device.OS != TargetPlatform.iOS && todo != null)
  44. {
  45. // Not iOS - the swipe-to-delete is discoverable there
  46. if (Device.OS == TargetPlatform.Android)
  47. {
  48. await DisplayAlert(todo.Name, "Press-and-hold to complete task " + todo.Name, "Got it!");
  49. }
  50. else
  51. {
  52. // Windows, not all platforms support the Context Actions yet
  53. if (await DisplayAlert("Mark completed?", "Do you wish to complete " + todo.Name + "?", "Complete", "Cancel"))
  54. {
  55. await CompleteItem(todo);
  56. }
  57. }
  58. }
  59. // prevents background getting highlighted
  60. todoList.SelectedItem = null;
  61. }
  62. // http://developer.xamarin.com/guides/cross-platform/xamarin-forms/working-with/listview/#context
  63. public async void OnComplete(object sender, EventArgs e)
  64. {
  65. var mi = ((MenuItem)sender);
  66. var todo = mi.CommandParameter as TodoItem;
  67. await CompleteItem(todo);
  68. }
  69. // http://developer.xamarin.com/guides/cross-platform/xamarin-forms/working-with/listview/#pulltorefresh
  70. public async void OnRefresh(object sender, EventArgs e)
  71. {
  72. var list = (ListView)sender;
  73. Exception error = null;
  74. try
  75. {
  76. await RefreshItems(false, true);
  77. }
  78. catch (Exception ex)
  79. {
  80. error = ex;
  81. }
  82. finally
  83. {
  84. list.EndRefresh();
  85. }
  86. if (error != null)
  87. {
  88. await DisplayAlert("Refresh Error", "Couldn't refresh data (" + error.Message + ")", "OK");
  89. }
  90. }
  91. public async void OnSyncItems(object sender, EventArgs e)
  92. {
  93. await RefreshItems(true, true);
  94. }
  95. private async Task RefreshItems(bool showActivityIndicator, bool syncItems)
  96. {
  97. using (var scope = new ActivityIndicatorScope(syncIndicator, showActivityIndicator))
  98. {
  99. todoList.ItemsSource = await manager.GetTodoItemsAsync(syncItems);
  100. }
  101. }
  102. private class ActivityIndicatorScope : IDisposable
  103. {
  104. private bool showIndicator;
  105. private ActivityIndicator indicator;
  106. private Task indicatorDelay;
  107. public ActivityIndicatorScope(ActivityIndicator indicator, bool showIndicator)
  108. {
  109. this.indicator = indicator;
  110. this.showIndicator = showIndicator;
  111. if (showIndicator)
  112. {
  113. indicatorDelay = Task.Delay(2000);
  114. SetIndicatorActivity(true);
  115. }
  116. else
  117. {
  118. indicatorDelay = Task.FromResult(0);
  119. }
  120. }
  121. private void SetIndicatorActivity(bool isActive)
  122. {
  123. this.indicator.IsVisible = isActive;
  124. this.indicator.IsRunning = isActive;
  125. }
  126. public void Dispose()
  127. {
  128. if (showIndicator)
  129. {
  130. indicatorDelay.ContinueWith(t => SetIndicatorActivity(false), TaskScheduler.FromCurrentSynchronizationContext());
  131. }
  132. }
  133. }
  134. }
  135. }