using System; using System.Globalization; using System.Linq; using System.Linq.Expressions; using InABox.Core; using JetBrains.Annotations; using Syncfusion.SfDataGrid.XForms; using Xamarin.Forms; namespace InABox.Mobile { public abstract class MobileGridColumn : IMobileGridColumn { [CanBeNull] public static IMobileGridColumn Create(Type entityType, String columnName) { var prop = CoreUtils.GetProperty(entityType, columnName); var baseType = CoreUtils.TypeList( new[] { typeof(MobileGridColumn).Assembly }, x=>x.IsSubclassOf(typeof(MobileGridColumn)) && !x.IsAbstract && x.BaseType?.GenericTypeArguments.Contains(prop.PropertyType) == true ).FirstOrDefault(); if (baseType != null) { var resultType = baseType.MakeGenericType(entityType); var result = (IMobileGridColumn)Activator.CreateInstance(resultType); result.ColumnName = columnName; return result; } return null; } public abstract Action Tapped { get; set; } public abstract string ColumnName { get; set; } public abstract GridLength Width { get; set; } public abstract string Caption { get; set; } public abstract TextAlignment Alignment { get; set; } public abstract GridColumn CreateColumn(); } public abstract class MobileGridColumn : MobileGridColumn { private Expression> _column; public Expression> Column { get => _column; set { _column = value; _columnName = Column?.ToString().Replace(" ","").Replace("x=>x.","") ?? ""; } } private String _columnName; public override String ColumnName { get => _columnName; set { _columnName = value; _column = CoreUtils.CreateLambdaExpression(value); } } public override GridLength Width { get; set; } = GridLength.Star; public override String Caption { get; set; } public override TextAlignment Alignment { get; set; } = TextAlignment.Center; public override Action Tapped { get; set; } protected virtual View HeaderContent() { var label = new Label() { Text = String.IsNullOrWhiteSpace(Caption) ? ColumnName : Caption, Margin = new Thickness(2,0), FontSize = Device.GetNamedSize(NamedSize.Micro, typeof(Label)), TextColor = Color.Black, VerticalTextAlignment = TextAlignment.Center, HorizontalTextAlignment = Alignment, }; return label; } private class MobileGridColumnConverter : IValueConverter { private readonly Func OnFormatValue; public MobileGridColumnConverter(Func onformatvalue) { OnFormatValue = onformatvalue; } public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { return OnFormatValue?.Invoke(value); } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { throw new NotImplementedException(); } } public TColumn CreateColumn() where TColumn : GridColumn, new() { var result = new TColumn(); result.MappingName = ColumnName; result.DisplayBinding = new Binding(ColumnName, BindingMode.OneWay, new MobileGridColumnConverter(FormatValue)); if (Width.IsStar) result.ColumnSizer = ColumnSizer.Star; else if (Width.IsAuto) result.ColumnSizer = ColumnSizer.Auto; else { result.ColumnSizer = ColumnSizer.None; result.Width = Width.Value; } result.TextAlignment = Alignment; result.CellStyle.Setters.Add(new Setter() { Property = GridCell.ForegroundProperty, Value = Color.Black }); result.HeaderTextAlignment = Alignment; result.HeaderText = Caption; result.Padding = 0; result.CellTextSize = Device.GetNamedSize(NamedSize.Micro, typeof(Label)); result.HeaderTemplate = new DataTemplate(() => { var layout = new Grid() { VerticalOptions = LayoutOptions.Fill, RowSpacing = 0, ColumnSpacing = 0 }; layout.RowDefinitions.Add(new RowDefinition() { Height = GridLength.Star }); layout.RowDefinitions.Add(new RowDefinition() { Height = 1 }); var content = HeaderContent(); content.SetValue(Grid.RowProperty,0); layout.Children.Add(content); var box = new BoxView() { HeightRequest = 1, BackgroundColor = Color.LightGray, Margin = 0 }; box.SetValue(Grid.RowProperty,1); layout.Children.Add(box); return layout; }); return result; } protected virtual object FormatValue(object value) { return value; } } }