123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538 |
- using comal.timesheets.Data_Classes;
- using System;
- using System.Collections.Generic;
- using System.Collections.ObjectModel;
- using System.Linq;
- using System.Reflection;
- using Xamarin.Forms;
- using Xamarin.Forms.Xaml;
- namespace comal.timesheets
- {
- public enum DataGridSaveType
- {
- None,
- Single,
- Multiple
- }
- public delegate void DataGridOptionsSet(string title, DataGridSaveType savetype = DataGridSaveType.None);
- [XamlCompilation(XamlCompilationOptions.Compile)]
- public partial class MobileDataGrid : ContentView
- {
- public List<DataGridViewModelItem> Items { get; set; }
- DataGridSaveType SaveType { get; set; }
- public event DataGridOptionsSet OnOptionsSet;
- bool bSearching = false;
- ObservableCollection<DataGridFilter> Filters = new ObservableCollection<DataGridFilter>();
- List<DataGridViewModelItem> CurrentItems = new List<DataGridViewModelItem>();
- PropertyInfo[] info = typeof(DataGridViewModelItem).GetProperties();
- Dictionary<string, List<string>> FilterOptions = new Dictionary<string, List<string>>();
- Type Type;
- public MobileDataGrid()
- {
- InitializeComponent();
- Items = new List<DataGridViewModelItem>();
- Filters.CollectionChanged += Filters_CollectionChanged;
- }
- public void Setup(List<DataGridViewModelItem> items, Type type, DataGridSaveType savetype = DataGridSaveType.None)
- {
- Type = type;
- Items = items;
- Device.BeginInvokeOnMainThread(() =>
- {
- SetupHeadersAndDataTemplate(items.First());
- Refresh(Items);
- });
- OnOptionsSet?.Invoke(type.Name, savetype);
- SaveType = savetype;
- }
- /// <summary>
- /// Never pass CurrentItems into this function - create an intermediate list first
- /// </summary>
- /// <param name="items"></param>
- private void Refresh(List<DataGridViewModelItem> items)
- {
- itemsListView.ItemsSource = items;
- countLbl.Text = items.Count + " Records";
- CurrentItems.Clear();
- foreach (var item in items)
- {
- CurrentItems.Add(item);
- }
- if (Filters.Any())
- filterBtnRow.Height = 80;
- else
- filterBtnRow.Height = 0;
- int count = 0;
- foreach (var column in Items.First().Data)
- {
- var filter = Filters.FirstOrDefault(x => x.ColNumber == "Col" + count);
- if (filter != null)
- ChangeHeaderColour(true, count);
- else
- ChangeHeaderColour(false, count);
- count++;
- }
- }
- public void SetupHeadersAndDataTemplate(DataGridViewModelItem item)
- {
- GenerateHeaders(item);
- }
- public void GenerateHeaders(DataGridViewModelItem item)
- {
- int count = 0;
- foreach (var tuple in item.Data)
- {
- CreateNewHeader(tuple.Item1, count);
- CreateFilterOption(count);
- count++;
- }
- }
- private void CreateFilterOption(int column)
- {
- List<string> options = new List<string>();
- foreach (var property in info)
- {
- if (property.Name == "Col" + column)
- foreach (var item in Items)
- {
- string value = GetStringValue(property, item);
- if (!options.Contains(value) && !string.IsNullOrWhiteSpace(value))
- options.Add(value);
- }
- }
- options.Sort();
- FilterOptions.Add("Col" + column, options);
- }
- private void CreateNewHeader(string name, int count)
- {
- headerGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
- DataGridHeaderRow header = new DataGridHeaderRow { ColumnName = name, ColumnNumber = count };
- header.Setup();
- header.OnDataGridHeaderFilterTapped += Header_OnDataGridHeaderFilterTapped;
- header.OnDataGridHeaderTapped += Header_OnDataGridHeaderTapped;
- headerGrid.Children.Add(SetGridValues(header, 0, count));
- CreateSearchEntry(name, count);
- }
- private void CreateSearchEntry(string name, int count)
- {
- var searchEnt = new DataGridSearchEntry(name, count);
- searchEnt.OnDataGridSearchEntryChanged += SearchEnt_OnDataGridSearchEntryChanged;
- searchEnt.IsEnabled = name == "Image" ? false : true;
- headerGrid.Children.Add(SetGridValues(searchEnt, 1, count));
- }
- private View SetGridValues(View view, int row, int column)
- {
- view.SetValue(Grid.RowProperty, row);
- view.SetValue(Grid.ColumnProperty, column);
- return view;
- }
- #region Events
- private void Row_Tapped(object sender, EventArgs e)
- {
- var item = itemsListView.SelectedItem as DataGridViewModelItem;
- if (item != null && SaveType != DataGridSaveType.None)
- {
- switch (SaveType)
- {
- case DataGridSaveType.Single:
- AddSelectionToLists(item);
- UnselectOthers(item);
- break;
- case DataGridSaveType.Multiple:
- AddSelectionToLists(item);
- break;
- }
- }
- List<DataGridViewModelItem> list = new List<DataGridViewModelItem>();
- foreach (var i in CurrentItems)
- list.Add(i);
- Refresh(list);
- }
- private void UnselectOthers(DataGridViewModelItem item)
- {
- UnselectItems(item, Items);
- UnselectItems(item, CurrentItems);
- }
- private void UnselectItems(DataGridViewModelItem item, List<DataGridViewModelItem> selectedlist)
- {
- var list = selectedlist.Where(x => x.IsSelected == true);
- foreach (var foundItem in list)
- {
- if (foundItem.ID != item.ID)
- foundItem.IsSelected = false;
- }
- }
- private void AddSelectionToLists(DataGridViewModelItem item)
- {
- bool selected = item.IsSelected;
- AddSelectionToList(selected, Items, item.ID);
- AddSelectionToList(selected, CurrentItems, item.ID);
- }
- private void AddSelectionToList(bool selected, List<DataGridViewModelItem> list, Guid ID)
- {
- var foundItem = list.FirstOrDefault(x => x.ID == ID);
- if (foundItem != null)
- foundItem.IsSelected = selected ? false : true;
- }
- private void SearchEnt_OnDataGridSearchEntryChanged(int columnnumber, string value, string colname)
- {
- if (string.IsNullOrWhiteSpace(value))
- Filters.Remove(Filters.FirstOrDefault(x => x.ColNumber == "Col" + columnnumber && x.FilterType == FilterType.Typed));
- else
- {
- if (Filters.FirstOrDefault(x => x.ColNumber == "Col" + columnnumber) != null)
- Filters.Remove(Filters.FirstOrDefault(x => x.ColNumber == "Col" + columnnumber && x.FilterType == FilterType.Typed));
- Filters.Add(new DataGridFilter(colname, "Col" + columnnumber, value, FindNumber(columnnumber), FilterType.Typed));
- }
- }
- private void Filters_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
- {
- if (bSearching)
- return;
- CheckFilterDisplay();
- bSearching = true;
- List<DataGridViewModelItem> finalList = new List<DataGridViewModelItem>();
- if (Filters.FirstOrDefault(x => x.FilterNumber == FilterNumber.Zero) != null)
- {
- var foundfilters = Filters.Where(x => x.FilterNumber == FilterNumber.Zero);
- foreach (var foundfilter in foundfilters)
- {
- foreach (DataGridViewModelItem item in RunSearch(Items, foundfilter.Value, "Col0"))
- finalList.Add(item);
- }
- }
- else
- {
- foreach (DataGridViewModelItem item in Items)
- finalList.Add(item);
- }
- if (Filters.FirstOrDefault(x => x.FilterNumber == FilterNumber.One) != null)
- {
- var foundfilters = Filters.Where(x => x.FilterNumber == FilterNumber.One);
- List<DataGridViewModelItem> intermediatelist = new List<DataGridViewModelItem>();
- foreach (var foundfilter in foundfilters)
- {
- foreach (DataGridViewModelItem item in RunSearch(finalList, foundfilter.Value, "Col1"))
- intermediatelist.Add(item);
- }
- finalList.Clear();
- foreach (DataGridViewModelItem item in intermediatelist)
- finalList.Add(item);
- }
- else if (finalList.Count == 0)
- {
- foreach (DataGridViewModelItem item in Items)
- finalList.Add(item);
- }
- if (Filters.FirstOrDefault(x => x.FilterNumber == FilterNumber.Two) != null)
- {
- var foundfilters = Filters.Where(x => x.FilterNumber == FilterNumber.Two);
- List<DataGridViewModelItem> intermediatelist = new List<DataGridViewModelItem>();
- foreach (var foundfilter in foundfilters)
- {
- foreach (DataGridViewModelItem item in RunSearch(finalList, foundfilter.Value, "Col2"))
- intermediatelist.Add(item);
- }
- finalList.Clear();
- foreach (DataGridViewModelItem item in intermediatelist)
- finalList.Add(item);
- }
- else if (finalList.Count == 0)
- {
- foreach (DataGridViewModelItem item in Items)
- finalList.Add(item);
- }
- if (Filters.FirstOrDefault(x => x.FilterNumber == FilterNumber.Three) != null)
- {
- var foundfilters = Filters.Where(x => x.FilterNumber == FilterNumber.Three);
- List<DataGridViewModelItem> intermediatelist = new List<DataGridViewModelItem>();
- foreach (var foundfilter in foundfilters)
- {
- foreach (DataGridViewModelItem item in RunSearch(finalList, foundfilter.Value, "Col3"))
- intermediatelist.Add(item);
- }
- finalList.Clear();
- foreach (DataGridViewModelItem item in intermediatelist)
- finalList.Add(item);
- }
- if (finalList.Count == 0 && Filters.Count == 0)
- {
- foreach (DataGridViewModelItem item in Items)
- finalList.Add(item);
- }
- else if (finalList.Count == Items.Count && Filters.Count > 0)
- finalList.Clear();
- Refresh(finalList);
- bSearching = false;
- }
- private void CheckFilterDisplay()
- {
- filterLayout.Children.Clear();
- foreach (var filter in Filters)
- {
- DataGridFilterView filterview = new DataGridFilterView(filter.DisplayValue, filter.FilterType, filter.ColNumber);
- filterview.OnFilterClosed += Filterview_OnFilterClosed;
- filterLayout.Children.Add(filterview);
- }
- }
- private void Filterview_OnFilterClosed(string value, FilterType type, string colnumber)
- {
- List<DataGridFilter> toRemove = new List<DataGridFilter>();
- foreach (var child in filterLayout.Children)
- {
- if (child.GetType() == typeof(DataGridFilterView))
- {
- if ((child as DataGridFilterView).Value == value && (child as DataGridFilterView).FilterType == type)
- {
- var filter = Filters.FirstOrDefault(x => x.DisplayValue == value && x.FilterType == type);
- if (filter != null)
- toRemove.Add(filter);
- }
- }
- }
- if (toRemove.First().FilterType == FilterType.Typed)
- {
- foreach (var child in headerGrid.Children)
- {
- if (child.GetType() == typeof(DataGridSearchEntry))
- {
- if ((child as DataGridSearchEntry).ColumnNumber == int.Parse(colnumber.Substring(3, 1)))
- (child as DataGridSearchEntry).Text = "";
- }
- }
- }
- Filters.Remove(toRemove.First());
- }
- private void Header_OnDataGridHeaderTapped(int columnnumber, SearchUtils.SortDirection sortdirection)
- {
- var intermediatelist = new List<DataGridViewModelItem>();
- foreach (var property in info)
- {
- if (property.Name == "Col" + columnnumber)
- {
- foreach (var item in SearchUtils.OrderByPropertyName(CurrentItems, "Col" + columnnumber, sortdirection))
- {
- intermediatelist.Add(item);
- }
- Refresh(intermediatelist);
- }
- }
- }
- private void Header_OnDataGridHeaderFilterTapped(int columnnumber, string columnname)
- {
- List<string> options = FilterOptions["Col" + columnnumber];
- List<DataGridFilter> filters = new List<DataGridFilter>();
- var selectedFilters = Filters.Where(x => x.FilterType == FilterType.Selected && x.ColNumber == "Col" + columnnumber);
- foreach (var list in selectedFilters)
- {
- filters.Add(list);
- }
- MultiSelectPage filterpage = new MultiSelectPage(options, filters, columnnumber, columnname);
- filterpage.OnPageSaved += FilterPage_OnPageSaved;
- Navigation.PushAsync(filterpage);
- }
- private void FilterPage_OnPageSaved(IEnumerable<MultiSelectPageViewItem> items, int columnnumber, string columnname)
- {
- var intermediateList = new List<DataGridFilter>();
- var list = Filters.Where(x => x.ColNumber == "Col" + columnnumber && x.FilterType == FilterType.Selected);
- foreach (var item in list)
- {
- intermediateList.Add(item);
- }
- foreach (var filter in intermediateList)
- Filters.Remove(filter);
- foreach (var item in items)
- Filters.Add(new DataGridFilter(columnname, "Col" + columnnumber, item.Value, FindNumber(columnnumber), FilterType.Selected));
- var newlist = Filters.Where(x => x.ColNumber == "Col" + columnnumber);
- }
- #endregion
- private IEnumerable<DataGridViewModelItem> RunSearch(IEnumerable<DataGridViewModelItem> list, string value, string propertyname)
- {
- var intermediatelist = new List<DataGridViewModelItem>();
- foreach (var property in info)
- {
- if (property.Name == propertyname)
- {
- foreach (var item in list)
- {
- if (GetStringValue(property, item).Contains(value)
- || GetStringValue(property, item).Contains(value.ToUpper())
- || GetStringValue(property, item).Contains(value.ToLower())
- || GetStringValue(property, item).Contains(SearchUtils.LowerCaseFirst(value))
- || GetStringValue(property, item).Contains(SearchUtils.UpperCaseFirst(value))
- || GetStringValue(property, item).Contains(SearchUtils.UpperCaseSecond(value))
- )
- {
- if (!intermediatelist.Contains(item))
- intermediatelist.Add(item);
- }
- }
- }
- }
- return intermediatelist;
- }
- private void ChangeHeaderColour(bool filterpresent, int colnumber)
- {
- foreach (var header in headerGrid.Children)
- {
- if (header.GetType() == typeof(DataGridHeaderRow))
- {
- if ((header as DataGridHeaderRow).ColumnNumber == colnumber)
- (header as DataGridHeaderRow).ChangeFilterColour(filterpresent);
- }
- }
- }
- private string GetStringValue(PropertyInfo property, object item)
- {
- if (property.PropertyType == typeof(string))
- return (string)property.GetValue(item);
- else
- return "";
- }
- private FilterNumber FindNumber(int columnnumber)
- {
- switch (columnnumber)
- {
- case 0:
- return FilterNumber.Zero;
- case 1:
- return FilterNumber.One;
- case 2:
- return FilterNumber.Two;
- case 3:
- return FilterNumber.Three;
- default:
- return FilterNumber.Zero;
- }
- }
- }
- public enum FilterNumber
- {
- Zero,
- One,
- Two,
- Three
- }
- public enum FilterType
- {
- Typed,
- Selected
- }
- public class DataGridFilter
- {
- public string ColNumber { get; set; }
- public string ColName { get; set; }
- public string Value { get; set; }
- public FilterNumber FilterNumber { get; set; }
- public FilterType FilterType { get; set; }
- public string DisplayValue
- {
- get => ColName + " = " + Value;
- }
- public DataGridFilter(string colname, string colNumber, string value, FilterNumber filterNumber, FilterType filterType)
- {
- ColName = colname;
- ColNumber = colNumber;
- Value = value;
- FilterNumber = filterNumber;
- FilterType = filterType;
- }
- }
- public class DataGridViewModelItem
- {
- public Guid ID { get; set; }
- private bool isSelected;
- public bool IsSelected
- {
- get
- {
- return isSelected;
- }
- set
- {
- isSelected = value;
- Color = isSelected == true ? Color.FromHex("#91a3b0") /*Cadet Gray*/ : Color.Default;
- }
- }
- public Color Color { get; set; }
- public List<Tuple<string, string>> Data { get; set; }
- public string Col0 { get; set; }
- public string Col1 { get; set; }
- public string Col2 { get; set; }
- public string Col3 { get; set; }
- public Image Image { get; set; }
- public ImageSource Source
- {
- get
- {
- return Image.Source;
- }
- }
- public GridLength ColWidth0 { get; set; }
- public GridLength ColWidth1 { get; set; }
- public GridLength ColWidth2 { get; set; }
- public GridLength ColWidth3 { get; set; }
- public DataGridViewModelItem(Guid id, List<Tuple<string, string>> data, Image image = null)
- {
- ID = id;
- Data = data;
- Image = image;
- Col0 = data.Count > 0 ? data[0].Item2 : "";
- Col1 = data.Count > 1 ? data[1].Item2 : "";
- Col2 = data.Count > 2 ? data[2].Item2 : "";
- Col3 = data.Count > 3 ? data[3].Item2 : "";
- ColWidth0 = data.Count > 0 ? new GridLength(1, GridUnitType.Star) : new GridLength(0, GridUnitType.Absolute);
- ColWidth1 = data.Count > 1 ? new GridLength(1, GridUnitType.Star) : new GridLength(0, GridUnitType.Absolute);
- ColWidth2 = data.Count > 2 ? new GridLength(1, GridUnitType.Star) : new GridLength(0, GridUnitType.Absolute);
- ColWidth3 = data.Count > 3 ? new GridLength(1, GridUnitType.Star) : new GridLength(0, GridUnitType.Absolute);
- IsSelected = false;
- }
- }
- }
|