using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Linq.Expressions; using InABox.Clients; using InABox.Core; using InABox.Mobile; using Xamarin.Forms; using XF.Material.Forms.UI; using XF.Material.Forms.UI.Dialogs; namespace PRS.Mobile { public class SelectionViewModelImageHeightConverter : AbstractConverter { public int Value { get; set; } protected override int Convert(ImageSource value, object? parameter = null) { return value != null ? Value : 0; } } public class ItemSelectedEventArgs : EventArgs { public CoreRow Row { get; private set; } public String Formatted { get; private set; } public ItemSelectedEventArgs(CoreRow row, String formatted) { Row = row; Formatted = formatted; } } public delegate void ItemSelectedEvent(object sender, ItemSelectedEventArgs args); public interface ISelectionViewModel { SelectionViewModelItem[] Load(); IFilter? Filter { get; set; } IColumns VisibleColumns { get; set; } Type Type { get; } } public class SelectionViewModelItem { public String Display { get; set; } public CoreRow Row { get; set; } public ImageSource Image { get; set; } } public class SelectionViewModel : ISelectionViewModel where T : Entity, IRemotable, IPersistent, new() { public Type Type => typeof(T); public IFilter? Filter { get; set; } public IColumns VisibleColumns { get; set; } public IColumns HiddenColumns { get; set; } public ISortOrder? Sort { get; set; } public Func? Format { get; set; } private Column? ImageColumn() { var columns = new Columns(ColumnTypeFlags.None).Add(x => x.ID); foreach (var column in VisibleColumns) columns.Add(column); foreach (var column in HiddenColumns) columns.Add(column); foreach (var column in columns) { var prop = CoreUtils.GetProperty(column.Property); var editor = EditorUtils.GetEditor(prop.PropertyType); if (editor is ImageDocumentEditor) return column; } return null; } public SelectionViewModel(Filter? filter, Expression>[] visible, Expression>[]? hidden = null, SortOrder? sort = null, Func? format = null) { Filter = filter; VisibleColumns = new Columns(ColumnTypeFlags.None); foreach (var visiblecolumn in visible) VisibleColumns.Add(visiblecolumn); HiddenColumns = new Columns(ColumnTypeFlags.None); if (hidden != null) { foreach (var hiddencolumn in hidden) HiddenColumns.Add(hiddencolumn); } Sort = sort; Format = format; } public SelectionViewModel() { Filter = LookupFactory.DefineFilter(); VisibleColumns = new Columns(ColumnTypeFlags.None); HiddenColumns = new Columns(ColumnTypeFlags.None); var columns = LookupFactory.DefineColumns(); foreach (var column in columns) { var editor = EditorUtils.GetEditor(CoreUtils.GetProperty(typeof(T), column.Property).PropertyType); if (editor?.Visible != Visible.Default) VisibleColumns.Add(column); else HiddenColumns.Add(column); } Sort = LookupFactory.DefineSort(); Format = row => LookupFactory.FormatLookup(row.ToDictionary(), new[] { "ID" }); } public SelectionViewModelItem[] Load() { var filter = Filter as Filter; var sort = Sort as SortOrder; var columns = new Columns(ColumnTypeFlags.None).Add(x=>x.ID); foreach (var column in VisibleColumns) columns.Add(column); foreach (var column in HiddenColumns) columns.Add(column); MultiQuery query = new MultiQuery(); query.Add(filter,columns,sort); var imgcol = ImageColumn(); if (imgcol != null) query.Add(new Filter(x => x.ID).InQuery(new SubQuery(filter, imgcol))); query.Query(); var data = query.Get(); var docs = query.Contains() ? query.Get().ToDictionary(x => x.ID, x => x.Data) : new Dictionary() { }; List items = new List(); foreach (var row in data.Rows) { String display = Format != null ? Format(row) : String.Join(" : ", VisibleColumns.ColumnNames().Select(x => row[x]).ToArray()); ImageSource img = (imgcol != null) && (docs.TryGetValue(row.Get(imgcol.Property), out byte[] imgdata)) ? ImageSource.FromStream(() => new MemoryStream(imgdata)) : null; items.Add(new SelectionViewModelItem() { Display = display, Row = row, Image = img }); } return items.ToArray(); } } public partial class GenericSelectionPage { public event ItemSelectedEvent OnItemSelected; private ISelectionViewModel _model; private SelectionViewModelItem[] _items = { }; public bool AutoClose { get; set; } = true; public GenericSelectionPage(String title, ISelectionViewModel model) { _model = model; InitializeComponent(); Title = title; } bool bFirst = true; protected override async void OnAppearing() { base.OnAppearing(); if (bFirst) { bFirst = false; var progress = await MaterialDialog.Instance.LoadingDialogAsync(message: "Loading Data"); _items = _model.Load(); _list.ItemsSource = _items; await progress.DismissAsync(); } } void Item_Selected(Object sender, SelectedItemChangedEventArgs e) { if (e.SelectedItem == null) return; SelectionViewModelItem selected = e.SelectedItem as SelectionViewModelItem; OnItemSelected?.Invoke(this, new ItemSelectedEventArgs(selected.Row, selected.Display)); if (AutoClose) Navigation.PopAsync(); } private void MobileSearchBar_OnTextChanged(object sender, MobileSearchBarTextChangedArgs args) { _list.ItemsSource = null; _list.ItemsSource = String.IsNullOrWhiteSpace(args.Text) ? _items : _items.Where(x => x.Display.ToUpper().Contains(args.Text.ToUpper())); } } }