MobileGrid.xaml.cs 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. using System;
  2. using System.Collections;
  3. using System.Linq;
  4. using System.Threading.Tasks;
  5. using System.Windows.Input;
  6. using InABox.Core;
  7. using InABox.Mobile.Shared;
  8. using Syncfusion.Data.Extensions;
  9. using Syncfusion.SfDataGrid.XForms;
  10. using Xamarin.Forms;
  11. using Xamarin.Forms.Xaml;
  12. namespace InABox.Mobile
  13. {
  14. public enum MobileGridSelectionMode
  15. {
  16. None,
  17. Single,
  18. Multiple
  19. }
  20. public class PullToRefreshCommand : ICommand
  21. {
  22. private readonly MobileGrid _grid;
  23. public bool CanExecute(object parameter)
  24. {
  25. return _grid.PullToRefresh;
  26. }
  27. public void Execute(object parameter)
  28. {
  29. _grid.RequestRefresh();
  30. }
  31. public event EventHandler CanExecuteChanged;
  32. public PullToRefreshCommand(MobileGrid grid)
  33. {
  34. _grid = grid;
  35. }
  36. }
  37. public class MobileGridSelectionArgs : EventArgs
  38. {
  39. public object[] Selection { get; private set; }
  40. public MobileGridSelectionArgs(object[] selection)
  41. {
  42. Selection = selection;
  43. }
  44. }
  45. public delegate void MobileGridSelectionChanged(object sender, MobileGridSelectionArgs args);
  46. public class MobileGridRefreshRequestArgs : EventArgs { }
  47. public delegate void MobileGridRefreshRequested(object sender, MobileGridRefreshRequestArgs args);
  48. [XamlCompilation(XamlCompilationOptions.Compile)]
  49. public partial class MobileGrid
  50. {
  51. public MobileGridColumns Columns { get; private set; }
  52. public object ItemsSource
  53. {
  54. get => Grid.ItemsSource;
  55. set
  56. {
  57. Grid.ItemsSource = value;
  58. UpdateSummaryRow();
  59. }
  60. }
  61. public object[] SelectedItems => Grid.SelectedItems.ToArray();
  62. private bool _canSearch = true;
  63. public bool CanSearch
  64. {
  65. get => _canSearch;
  66. set
  67. {
  68. _canSearch = value;
  69. CheckSearchVisibility();
  70. }
  71. }
  72. public static readonly BindableProperty PullToRefreshProperty = BindableProperty.Create(
  73. nameof(PullToRefresh),
  74. typeof(bool),
  75. typeof(MobileGrid));
  76. public bool PullToRefresh
  77. {
  78. get => (bool)GetValue(PullToRefreshProperty);
  79. set
  80. {
  81. SetValue(PullToRefreshProperty, value);
  82. UpdateSummaryRow();
  83. }
  84. }
  85. public static readonly BindableProperty LastUpdatedProperty = BindableProperty.Create(
  86. nameof(LastUpdated),
  87. typeof(DateTime),
  88. typeof(MobileGrid));
  89. public DateTime LastUpdated
  90. {
  91. get => (DateTime)GetValue(LastUpdatedProperty);
  92. set
  93. {
  94. SetValue(LastUpdatedProperty,value);
  95. UpdateSummaryRow();
  96. }
  97. }
  98. public static readonly BindableProperty ShowRecordCountProperty = BindableProperty.Create(
  99. nameof(ShowRecordCount),
  100. typeof(bool),
  101. typeof(MobileGrid),
  102. false);
  103. public bool ShowRecordCount
  104. {
  105. get => (bool)GetValue(ShowRecordCountProperty);
  106. set
  107. {
  108. SetValue(ShowRecordCountProperty,value);
  109. UpdateSummaryRow();
  110. }
  111. }
  112. private void UpdateSummaryRow()
  113. {
  114. _lastupdate.IsVisible = !LastUpdated.IsEmpty();
  115. _lastupdate.Text = $"{DateTimeToAgeConverter.FormatTime(LastUpdated)}";
  116. _pulltorefresh.IsVisible = PullToRefresh;
  117. _numrecords.Text = $"{(ItemsSource as IEnumerable)?.ToList<object>().Count() ?? 0} records";
  118. _numrecords.IsVisible = ShowRecordCount && (ItemsSource is IEnumerable);
  119. _refreshgrid.IsVisible = _lastupdate.IsVisible || _pulltorefresh.IsVisible || _numrecords.IsVisible;
  120. }
  121. public MobileGridSelectionMode SelectionMode
  122. {
  123. get => Grid.SelectionMode == Syncfusion.SfDataGrid.XForms.SelectionMode.Multiple
  124. ? MobileGridSelectionMode.Multiple
  125. : Grid.SelectionMode == Syncfusion.SfDataGrid.XForms.SelectionMode.Single
  126. ? MobileGridSelectionMode.Single
  127. : MobileGridSelectionMode.None;
  128. set => Grid.SelectionMode = value == MobileGridSelectionMode.Multiple
  129. ? Syncfusion.SfDataGrid.XForms.SelectionMode.Multiple
  130. : value == MobileGridSelectionMode.Single
  131. ? Syncfusion.SfDataGrid.XForms.SelectionMode.SingleDeselect
  132. : Syncfusion.SfDataGrid.XForms.SelectionMode.None;
  133. }
  134. public event MobileGridSelectionChanged SelectionChanged;
  135. public event MobileGridRefreshRequested RefreshRequested;
  136. internal void RequestRefresh()
  137. {
  138. var src = ItemsSource;
  139. ItemsSource = null;
  140. RefreshRequested?.Invoke(this, new MobileGridRefreshRequestArgs());
  141. ItemsSource = src;
  142. }
  143. private String _searchText = "";
  144. bool DoSearch(object data)
  145. {
  146. if (String.IsNullOrWhiteSpace(_searchText))
  147. return true;
  148. foreach (var col in Grid.Columns)
  149. {
  150. var property = data.GetType().GetProperty(col.MappingName);
  151. if (property != null && property.PropertyType != typeof(ImageSource))
  152. {
  153. var value = property.GetValue(data);
  154. var sValue = String.IsNullOrWhiteSpace(col.Format)
  155. ? value?.ToString() ?? ""
  156. : String.Format($"{{0:{col.Format}}}", value);
  157. if (sValue.ToUpper().Contains(_searchText))
  158. return true;
  159. }
  160. }
  161. return false;
  162. }
  163. public double RowHeight
  164. {
  165. get => Grid.RowHeight;
  166. set => Grid.RowHeight = value;
  167. }
  168. public void ClearSelection()
  169. {
  170. Grid.SelectedItem = null;
  171. Grid.SelectedItems.Clear();
  172. }
  173. public MobileGrid()
  174. {
  175. InitializeComponent();
  176. Columns = new MobileGridColumns(Grid);
  177. Columns.Changed += (sender, args) => CheckSearchVisibility();
  178. SelectionMode = MobileGridSelectionMode.Single;
  179. CanSearch = true;
  180. Grid.PullToRefreshCommand = new PullToRefreshCommand(this);
  181. Grid.QueryCellStyle += (sender, args) =>
  182. {
  183. args.Style.FontSize = Device.GetNamedSize(NamedSize.Micro, typeof(Label));
  184. };
  185. }
  186. private void Search_OnTextChanged(object sender, MobileSearchBarTextChangedArgs args)
  187. {
  188. _searchText = args.Text?.ToUpper() ?? "";
  189. Grid.View.Filter = DoSearch;
  190. Grid.View.RefreshFilter(true);
  191. UpdateSummaryRow();
  192. }
  193. private void Grid_OnGridViewCreated(object sender, GridViewCreatedEventArgs e)
  194. {
  195. CheckSearchVisibility();
  196. }
  197. private void CheckSearchVisibility()
  198. {
  199. var searchables = Grid.Columns.Any(x=>(x is GridImageColumn) == false);
  200. Search.IsVisible = searchables && CanSearch;
  201. // if (Grid.View != null)
  202. // {
  203. // if (Search.IsVisible)
  204. // Grid.View.Filter = DoSearch;
  205. // else
  206. // Grid.View.Filter = null;
  207. // }
  208. }
  209. private void Grid_OnSelectionChanged(object sender, GridSelectionChangedEventArgs e)
  210. {
  211. //SelectionChanged?.Invoke(this, new MobileGridSelectionArgs(Grid.SelectedItems.ToArray()));
  212. }
  213. private void Grid_OnGridTapped(object sender, GridTappedEventArgs e)
  214. {
  215. if (SelectionMode == MobileGridSelectionMode.Multiple)
  216. return;
  217. var column = Columns[e.RowColumnIndex.ColumnIndex];
  218. if (column.Tapped != null)
  219. column.Tapped?.Invoke(column, e.RowData);
  220. else
  221. SelectionChanged?.Invoke(this, new MobileGridSelectionArgs(new [] { e.RowData }));
  222. }
  223. // private void SfPullToRefresh_OnRefreshing(object sender, EventArgs e)
  224. // {
  225. // pullToRefresh.IsRefreshing = true;
  226. // var _items = ItemsSource;
  227. // ItemsSource = null;
  228. // RefreshRequested?.Invoke(this, new MobileGridRefreshRequestArgs());
  229. // pullToRefresh.IsRefreshing = false;
  230. // ItemsSource = _items;
  231. // }
  232. }
  233. }