| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278 | using System;using System.Collections;using System.Linq;using System.Threading.Tasks;using System.Windows.Input;using InABox.Core;using InABox.Mobile.Shared;using Syncfusion.Data.Extensions;using Syncfusion.SfDataGrid.XForms;using Xamarin.Forms;using Xamarin.Forms.Xaml;namespace InABox.Mobile{    public enum MobileGridSelectionMode    {        None,        Single,        Multiple    }    public class PullToRefreshCommand : ICommand    {            private readonly MobileGrid _grid;                public bool CanExecute(object parameter)        {            return _grid.PullToRefresh;        }            public void Execute(object parameter)        {            _grid.RequestRefresh();        }            public event EventHandler CanExecuteChanged;            public PullToRefreshCommand(MobileGrid grid)        {            _grid = grid;        }    }    public class MobileGridSelectionArgs : EventArgs    {        public object[] Selection { get; private set; }        public MobileGridSelectionArgs(object[] selection)        {            Selection = selection;        }    }            public delegate void MobileGridSelectionChanged(object sender, MobileGridSelectionArgs args);        public class MobileGridRefreshRequestArgs : EventArgs { }        public delegate void MobileGridRefreshRequested(object sender, MobileGridRefreshRequestArgs args);        [XamlCompilation(XamlCompilationOptions.Compile)]    public partial class MobileGrid    {        public MobileGridColumns Columns { get; private set; }                public object ItemsSource        {            get => Grid.ItemsSource;            set            {                Grid.ItemsSource = value;                UpdateSummaryRow();            }        }        public object[] SelectedItems => Grid.SelectedItems.ToArray();        private bool _canSearch = true;        public bool CanSearch         {             get => _canSearch;            set            {                _canSearch = value;                CheckSearchVisibility();            }        }                public static readonly BindableProperty PullToRefreshProperty = BindableProperty.Create(            nameof(PullToRefresh),             typeof(bool),             typeof(MobileGrid));        public bool PullToRefresh        {            get => (bool)GetValue(PullToRefreshProperty);            set            {                SetValue(PullToRefreshProperty, value);                UpdateSummaryRow();            }        }        public static readonly BindableProperty LastUpdatedProperty = BindableProperty.Create(            nameof(LastUpdated),             typeof(DateTime),             typeof(MobileGrid));                public DateTime LastUpdated        {            get => (DateTime)GetValue(LastUpdatedProperty);            set            {                SetValue(LastUpdatedProperty,value);                UpdateSummaryRow();            }        }                public static readonly BindableProperty ShowRecordCountProperty = BindableProperty.Create(            nameof(ShowRecordCount),             typeof(bool),             typeof(MobileGrid),             false);        public bool ShowRecordCount        {            get => (bool)GetValue(ShowRecordCountProperty);            set            {                SetValue(ShowRecordCountProperty,value);                UpdateSummaryRow();            }        }        private void UpdateSummaryRow()        {            _lastupdate.IsVisible = !LastUpdated.IsEmpty();            _lastupdate.Text = $"{DateTimeToAgeConverter.FormatTime(LastUpdated)}";            _pulltorefresh.IsVisible = PullToRefresh;            _numrecords.Text = $"{(ItemsSource as IList)?.Count ?? 0} records";            _numrecords.IsVisible = ShowRecordCount && (ItemsSource is IList);            _refreshgrid.IsVisible = _lastupdate.IsVisible || _pulltorefresh.IsVisible || _numrecords.IsVisible;        }                public MobileGridSelectionMode SelectionMode        {                        get => Grid.SelectionMode == Syncfusion.SfDataGrid.XForms.SelectionMode.Multiple                ? MobileGridSelectionMode.Multiple                : Grid.SelectionMode == Syncfusion.SfDataGrid.XForms.SelectionMode.Single                    ? MobileGridSelectionMode.Single                    : MobileGridSelectionMode.None;                        set => Grid.SelectionMode = value == MobileGridSelectionMode.Multiple                ? Syncfusion.SfDataGrid.XForms.SelectionMode.Multiple                : value == MobileGridSelectionMode.Single                     ? Syncfusion.SfDataGrid.XForms.SelectionMode.SingleDeselect                    : Syncfusion.SfDataGrid.XForms.SelectionMode.None;        }        public event MobileGridSelectionChanged SelectionChanged;                public event MobileGridRefreshRequested RefreshRequested;        internal void RequestRefresh()        {            var src = ItemsSource;            ItemsSource = null;            RefreshRequested?.Invoke(this, new MobileGridRefreshRequestArgs());            ItemsSource = src;        }        private String _searchText = "";                bool DoSearch(object data)        {            if (String.IsNullOrWhiteSpace(_searchText))                return true;            foreach (var col in Grid.Columns)            {                var property = data.GetType().GetProperty(col.MappingName);                if (property != null && property.PropertyType != typeof(ImageSource))                {                    var value = property.GetValue(data);                    var sValue = String.IsNullOrWhiteSpace(col.Format)                        ? value?.ToString() ?? ""                        : String.Format($"{{0:{col.Format}}}", value);                    if (sValue.ToUpper().Contains(_searchText))                        return true;                }            }            return false;        }        public double RowHeight        {            get => Grid.RowHeight;            set => Grid.RowHeight = value;        }        public void ClearSelection()        {            Grid.SelectedItem = null;            Grid.SelectedItems.Clear();        }                public MobileGrid()        {            InitializeComponent();            Columns = new MobileGridColumns(Grid);            Columns.Changed += (sender, args) => CheckSearchVisibility();             SelectionMode = MobileGridSelectionMode.Single;            CanSearch = true;            Grid.PullToRefreshCommand = new PullToRefreshCommand(this);            Grid.QueryCellStyle += (sender, args) =>            {                args.Style.FontSize = Device.GetNamedSize(NamedSize.Micro, typeof(Label));            };        }                private void Search_OnTextChanged(object sender, MobileSearchBarTextChangedArgs args)        {            _searchText = args.Text?.ToUpper() ?? "";            Grid.View.Filter = DoSearch;            Grid.View.RefreshFilter(true);            UpdateSummaryRow();        }        private void Grid_OnGridViewCreated(object sender, GridViewCreatedEventArgs e)        {            CheckSearchVisibility();        }        private void CheckSearchVisibility()        {            var searchables = Grid.Columns.Any(x=>(x is GridImageColumn) == false);            Search.IsVisible = searchables && CanSearch;            // if (Grid.View != null)            // {            //     if (Search.IsVisible)            //         Grid.View.Filter = DoSearch;            //     else            //         Grid.View.Filter = null;            // }        }        private void Grid_OnSelectionChanged(object sender, GridSelectionChangedEventArgs e)        {            //SelectionChanged?.Invoke(this, new MobileGridSelectionArgs(Grid.SelectedItems.ToArray()));        }        private void Grid_OnGridTapped(object sender, GridTappedEventArgs e)        {            if (SelectionMode == MobileGridSelectionMode.Multiple)                return;            var column = Columns[e.RowColumnIndex.ColumnIndex];            if (column.Tapped != null)                column.Tapped?.Invoke(column, e.RowData);            else                SelectionChanged?.Invoke(this, new MobileGridSelectionArgs(new [] { e.RowData }));                    }                // private void SfPullToRefresh_OnRefreshing(object sender, EventArgs e)        // {        //     pullToRefresh.IsRefreshing = true;        //     var _items = ItemsSource;        //     ItemsSource = null;        //     RefreshRequested?.Invoke(this, new MobileGridRefreshRequestArgs());        //     pullToRefresh.IsRefreshing = false;        //     ItemsSource = _items;        // }            }}
 |