GenericSelectionPage.xaml.cs 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Linq;
  5. using System.Linq.Expressions;
  6. using InABox.Clients;
  7. using InABox.Core;
  8. using InABox.Mobile;
  9. using Xamarin.Forms;
  10. using XF.Material.Forms.UI;
  11. using XF.Material.Forms.UI.Dialogs;
  12. namespace PRS.Mobile
  13. {
  14. public class SelectionViewModelImageHeightConverter : AbstractConverter<ImageSource, int>
  15. {
  16. public int Value { get; set; }
  17. protected override int Convert(ImageSource value, object? parameter = null)
  18. {
  19. return value != null ? Value : 0;
  20. }
  21. }
  22. public class ItemSelectedEventArgs : EventArgs
  23. {
  24. public CoreRow Row { get; private set; }
  25. public String Formatted { get; private set; }
  26. public ItemSelectedEventArgs(CoreRow row, String formatted)
  27. {
  28. Row = row;
  29. Formatted = formatted;
  30. }
  31. }
  32. public delegate void ItemSelectedEvent(object sender, ItemSelectedEventArgs args);
  33. public interface ISelectionViewModel
  34. {
  35. SelectionViewModelItem[] Load();
  36. IFilter? Filter { get; set; }
  37. IColumns VisibleColumns { get; set; }
  38. Type Type { get; }
  39. }
  40. public class SelectionViewModelItem
  41. {
  42. public String Display { get; set; }
  43. public CoreRow Row { get; set; }
  44. public ImageSource Image { get; set; }
  45. }
  46. public class SelectionViewModel<T> : ISelectionViewModel where T : Entity, IRemotable, IPersistent, new()
  47. {
  48. public Type Type => typeof(T);
  49. public IFilter? Filter { get; set; }
  50. public IColumns VisibleColumns { get; set; }
  51. public IColumns HiddenColumns { get; set; }
  52. public ISortOrder? Sort { get; set; }
  53. public Func<CoreRow, string>? Format { get; set; }
  54. private Column<T>? ImageColumn()
  55. {
  56. var columns = new Columns<T>(ColumnTypeFlags.None).Add(x => x.ID);
  57. foreach (var column in VisibleColumns)
  58. columns.Add(column);
  59. foreach (var column in HiddenColumns)
  60. columns.Add(column);
  61. foreach (var column in columns)
  62. {
  63. var prop = CoreUtils.GetProperty<T>(column.Property);
  64. var editor = EditorUtils.GetEditor(prop.PropertyType);
  65. if (editor is ImageDocumentEditor)
  66. return column;
  67. }
  68. return null;
  69. }
  70. public SelectionViewModel(Filter<T>? filter, Expression<Func<T, object>>[] visible, Expression<Func<T, object>>[]? hidden = null, SortOrder<T>? sort = null, Func<CoreRow, string>? format = null)
  71. {
  72. Filter = filter;
  73. VisibleColumns = new Columns<T>(ColumnTypeFlags.None);
  74. foreach (var visiblecolumn in visible)
  75. VisibleColumns.Add(visiblecolumn);
  76. HiddenColumns = new Columns<T>(ColumnTypeFlags.None);
  77. if (hidden != null)
  78. {
  79. foreach (var hiddencolumn in hidden)
  80. HiddenColumns.Add(hiddencolumn);
  81. }
  82. Sort = sort;
  83. Format = format;
  84. }
  85. public SelectionViewModel()
  86. {
  87. Filter = LookupFactory.DefineFilter<T>();
  88. VisibleColumns = new Columns<T>(ColumnTypeFlags.None);
  89. HiddenColumns = new Columns<T>(ColumnTypeFlags.None);
  90. var columns = LookupFactory.DefineColumns<T>();
  91. foreach (var column in columns)
  92. {
  93. var editor = EditorUtils.GetEditor(CoreUtils.GetProperty(typeof(T), column.Property).PropertyType);
  94. if (editor?.Visible != Visible.Default)
  95. VisibleColumns.Add(column);
  96. else
  97. HiddenColumns.Add(column);
  98. }
  99. Sort = LookupFactory.DefineSort<T>();
  100. Format = row => LookupFactory.FormatLookup<T>(row.ToDictionary(), new[] { "ID" });
  101. }
  102. public SelectionViewModelItem[] Load()
  103. {
  104. var filter = Filter as Filter<T>;
  105. var sort = Sort as SortOrder<T>;
  106. var columns = new Columns<T>(ColumnTypeFlags.None).Add(x=>x.ID);
  107. foreach (var column in VisibleColumns)
  108. columns.Add(column);
  109. foreach (var column in HiddenColumns)
  110. columns.Add(column);
  111. MultiQuery query = new MultiQuery();
  112. query.Add<T>(filter,columns,sort);
  113. var imgcol = ImageColumn();
  114. if (imgcol != null)
  115. query.Add(new Filter<Document>(x => x.ID).InQuery<T>(new SubQuery<T>(filter, imgcol)));
  116. query.Query();
  117. var data = query.Get<T>();
  118. var docs = query.Contains<Document>()
  119. ? query.Get<Document>().ToDictionary<Document, Guid, byte[]>(x => x.ID, x => x.Data)
  120. : new Dictionary<Guid, byte[]>() { };
  121. List<SelectionViewModelItem> items = new List<SelectionViewModelItem>();
  122. foreach (var row in data.Rows)
  123. {
  124. String display = Format != null
  125. ? Format(row)
  126. : String.Join(" : ", VisibleColumns.ColumnNames().Select(x => row[x]).ToArray());
  127. ImageSource img = (imgcol != null) && (docs.TryGetValue(row.Get<Guid>(imgcol.Property), out byte[] imgdata))
  128. ? ImageSource.FromStream(() => new MemoryStream(imgdata))
  129. : null;
  130. items.Add(new SelectionViewModelItem()
  131. {
  132. Display = display, Row = row, Image = img
  133. });
  134. }
  135. return items.ToArray();
  136. }
  137. }
  138. public partial class GenericSelectionPage
  139. {
  140. public event ItemSelectedEvent OnItemSelected;
  141. private ISelectionViewModel _model;
  142. private SelectionViewModelItem[] _items = { };
  143. public bool AutoClose { get; set; } = true;
  144. public GenericSelectionPage(String title, ISelectionViewModel model)
  145. {
  146. _model = model;
  147. InitializeComponent();
  148. Title = title;
  149. }
  150. bool bFirst = true;
  151. protected override async void OnAppearing()
  152. {
  153. base.OnAppearing();
  154. if (bFirst)
  155. {
  156. bFirst = false;
  157. var progress = await MaterialDialog.Instance.LoadingDialogAsync(message: "Loading Data");
  158. _items = _model.Load();
  159. _list.ItemsSource = _items;
  160. await progress.DismissAsync();
  161. }
  162. }
  163. void Item_Selected(Object sender, SelectedItemChangedEventArgs e)
  164. {
  165. if (e.SelectedItem == null)
  166. return;
  167. SelectionViewModelItem selected = e.SelectedItem as SelectionViewModelItem;
  168. OnItemSelected?.Invoke(this, new ItemSelectedEventArgs(selected.Row, selected.Display));
  169. if (AutoClose)
  170. Navigation.PopAsync();
  171. }
  172. private void MobileSearchBar_OnTextChanged(object sender, MobileSearchBarTextChangedArgs args)
  173. {
  174. _list.ItemsSource = null;
  175. _list.ItemsSource = String.IsNullOrWhiteSpace(args.Text)
  176. ? _items
  177. : _items.Where(x => x.Display.ToUpper().Contains(args.Text.ToUpper()));
  178. }
  179. }
  180. }