MobileToolGrid.xaml.cs 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Collections.ObjectModel;
  4. using System.Globalization;
  5. using System.Linq;
  6. using System.Threading.Tasks;
  7. using Xamarin.Essentials;
  8. using Xamarin.Forms;
  9. using Xamarin.Forms.Xaml;
  10. using XF.Material.Forms;
  11. namespace InABox.Mobile
  12. {
  13. public class ToolGridLayoutChangedEventArgs : EventArgs
  14. {
  15. public int RowCount { get; private set; }
  16. public int ColCount { get; private set; }
  17. public ToolGridLayoutChangedEventArgs(int rowcount, int colcount)
  18. {
  19. RowCount = rowcount;
  20. ColCount = colcount;
  21. }
  22. }
  23. public delegate void ToolGridLayoutChangedEvent(object sender, ToolGridLayoutChangedEventArgs args);
  24. public class ToolGridViewModel : BindableObject
  25. {
  26. public IList<IMobileToolItem> Items { get; private set; }
  27. public IList<IMobileToolItem> VisibleItems { get; private set; }
  28. public int Columns { get; set; }
  29. public ToolGridViewModel()
  30. {
  31. Columns = Device.Idiom == TargetIdiom.Tablet ? 6 : 4;
  32. Items = new ObservableCollection<IMobileToolItem>();
  33. VisibleItems = new ObservableCollection<IMobileToolItem>();
  34. ((ObservableCollection<IMobileToolItem>)Items).CollectionChanged += (sender, args) =>
  35. {
  36. Refresh();
  37. };
  38. }
  39. public void Refresh()
  40. {
  41. VisibleItems.Clear();
  42. DoLayout();
  43. }
  44. private void DoLayout()
  45. {
  46. int iRow = 0;
  47. int iCol = 0;
  48. foreach (var item in Items.Where(x => x.IsVisible))
  49. {
  50. item.Row = iRow;
  51. item.Column = iCol;
  52. VisibleItems.Add(item);
  53. iCol++;
  54. if (iCol == Columns)
  55. {
  56. iRow++;
  57. iCol = 0;
  58. }
  59. }
  60. LayoutChanged?.Invoke(this,new ToolGridLayoutChangedEventArgs(iRow,Columns));
  61. }
  62. public Color BackgroundColor { get; set; }
  63. public event ToolGridLayoutChangedEvent LayoutChanged;
  64. }
  65. [XamlCompilation(XamlCompilationOptions.Compile)]
  66. public partial class MobileToolGrid
  67. {
  68. public IList<IMobileToolItem> Items => _viewModel.Items;
  69. public event EventHandler BeforeTap;
  70. public event EventHandler AfterTap;
  71. public MobileToolGrid()
  72. {
  73. InitializeComponent();
  74. BindableLayout.SetItemsSource(_flexgrid, _viewModel.VisibleItems);
  75. }
  76. public void Refresh()
  77. {
  78. _viewModel.Refresh();
  79. }
  80. private readonly BindableProperty BorderColorProperty = BindableProperty.Create(
  81. nameof(BorderColor),
  82. typeof(Color),
  83. typeof(MobileToolGrid),
  84. Material.Color.SecondaryVariant
  85. );
  86. public Color BorderColor
  87. {
  88. get => (Color)GetValue(BorderColorProperty);
  89. set => SetValue(BorderColorProperty, value);
  90. }
  91. private bool debounce = false;
  92. private async void ToolItem_Tapped(object sender, EventArgs e)
  93. {
  94. if (debounce)
  95. return;
  96. debounce = true;
  97. BeforeTap?.Invoke(this, EventArgs.Empty);
  98. try
  99. {
  100. if ((sender is Frame frame) && (frame.BindingContext is MobileToolItem item) && item.IsEnabled)
  101. {
  102. frame.Scale = 0.5;
  103. await frame.ScaleTo(1, 150);
  104. item.DoTap();
  105. }
  106. }
  107. catch (Exception err)
  108. {
  109. MobileLogging.Log(err,"MobileToolGrid");
  110. }
  111. AfterTap?.Invoke(this, EventArgs.Empty);
  112. debounce = false;
  113. }
  114. private void _viewModel_OnLayoutChanged(object sender, ToolGridLayoutChangedEventArgs args)
  115. {
  116. _flexgrid.RowDefinitions.Clear();
  117. for (int i=0; i< args.RowCount; i++)
  118. _flexgrid.RowDefinitions.Add(new RowDefinition() { Height = GridLength.Auto});
  119. _flexgrid.ColumnDefinitions.Clear();
  120. for (int i=0; i< args.ColCount; i++)
  121. _flexgrid.ColumnDefinitions.Add(new ColumnDefinition() { Width = GridLength.Star});
  122. }
  123. }
  124. }