diff --git a/src/Android/Renderers/BoxedView/BoxedViewRecyclerAdapter.cs b/src/Android/Renderers/BoxedView/BoxedViewRecyclerAdapter.cs index ca91f39f6..fe15d37c5 100644 --- a/src/Android/Renderers/BoxedView/BoxedViewRecyclerAdapter.cs +++ b/src/Android/Renderers/BoxedView/BoxedViewRecyclerAdapter.cs @@ -12,7 +12,7 @@ using Xamarin.Forms; using Xamarin.Forms.Platform.Android; using AView = Android.Views.View; -namespace Bit.Droid.Renderers +namespace Bit.Droid.Renderers.BoxedView { [Preserve(AllMembers = true)] public class BoxedViewRecyclerAdapter : RecyclerView.Adapter, AView.IOnClickListener @@ -20,8 +20,6 @@ namespace Bit.Droid.Renderers private const int ViewTypeHeader = 0; private const int ViewTypeFooter = 1; - private float MinRowHeight => _context.ToPixels(44); - private Dictionary _viewTypes; private List _cellCaches; @@ -42,28 +40,21 @@ namespace Bit.Droid.Renderers private AView _preSelectedCell = null; Context _context; - BoxedView _boxedView; + App.Controls.BoxedView.BoxedView _boxedView; RecyclerView _recyclerView; List _viewHolders = new List(); - public BoxedViewRecyclerAdapter(Context context, BoxedView boxedView, RecyclerView recyclerView) + public BoxedViewRecyclerAdapter(Context context, App.Controls.BoxedView.BoxedView boxedView, + RecyclerView recyclerView) { _context = context; _boxedView = boxedView; _recyclerView = recyclerView; - - _boxedView.ModelChanged += _boxedView_ModelChanged; + _boxedView.ModelChanged += BoxedView_ModelChanged; } - void _boxedView_ModelChanged(object sender, EventArgs e) - { - if(_recyclerView != null) - { - _cellCaches = null; - NotifyDataSetChanged(); - } - } + private float MinRowHeight => _context.ToPixels(44); public override int ItemCount => CellCaches.Count; @@ -101,28 +92,24 @@ namespace Bit.Droid.Renderers { var position = _recyclerView.GetChildAdapterPosition(view); - //TODO: It is desirable that the forms side has Selected property and reflects it. - // But do it at a later as iOS side doesn't have that process. + // TODO: It is desirable that the forms side has Selected property and reflects it. + // But do it at a later as iOS side doesn't have that process. DeselectRow(); var cell = view.FindViewById(Resource.Id.ContentCellBody).GetChildAt(0) as BaseCellView; - - if(cell == null || !CellCaches[position].Cell.IsEnabled) { - //if FormsCell IsEnable is false, does nothing. + // If FormsCell IsEnable is false, does nothing. return; } _boxedView.Model.RowSelected(CellCaches[position].Cell); - cell.RowSelected(this, position); } public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position) { var cellInfo = CellCaches[position]; - switch(holder.ItemViewType) { case ViewTypeHeader: @@ -175,7 +162,7 @@ namespace Bit.Droid.Renderers { if(disposing) { - _boxedView.ModelChanged -= _boxedView_ModelChanged; + _boxedView.ModelChanged -= BoxedView_ModelChanged; _cellCaches?.Clear(); _cellCaches = null; _boxedView = null; @@ -190,12 +177,20 @@ namespace Bit.Droid.Renderers base.Dispose(disposing); } + private void BoxedView_ModelChanged(object sender, EventArgs e) + { + if(_recyclerView != null) + { + _cellCaches = null; + NotifyDataSetChanged(); + } + } private void BindHeaderView(HeaderViewHolder holder, TextCell formsCell) { var view = holder.ItemView; - //judging cell height + // Judging cell height int cellHeight = (int)_context.ToPixels(44); var individualHeight = formsCell.Height; @@ -211,7 +206,6 @@ namespace Bit.Droid.Renderers view.SetMinimumHeight(cellHeight); view.LayoutParameters.Height = cellHeight; - //textview setting holder.TextView.SetPadding( (int)view.Context.ToPixels(_boxedView.HeaderPadding.Left), (int)view.Context.ToPixels(_boxedView.HeaderPadding.Top), @@ -231,7 +225,7 @@ namespace Bit.Droid.Renderers holder.TextView.SetTextColor(_boxedView.HeaderTextColor.ToAndroid()); } - //border setting + // Border setting if(_boxedView.ShowSectionTopBottomBorder) { holder.Border.SetBackgroundColor(_boxedView.SeparatorColor.ToAndroid()); @@ -241,7 +235,7 @@ namespace Bit.Droid.Renderers holder.Border.SetBackgroundColor(Android.Graphics.Color.Transparent); } - //update text + // Update text holder.TextView.Text = formsCell.Text; } @@ -249,7 +243,7 @@ namespace Bit.Droid.Renderers { var view = holder.ItemView; - //footer visible setting + // Footer visible setting if(string.IsNullOrEmpty(formsCell.Text)) { //if text is empty, hidden (height 0) @@ -262,7 +256,6 @@ namespace Bit.Droid.Renderers view.Visibility = ViewStates.Visible; } - //textview setting holder.TextView.SetPadding( (int)view.Context.ToPixels(_boxedView.FooterPadding.Left), (int)view.Context.ToPixels(_boxedView.FooterPadding.Top), @@ -276,7 +269,7 @@ namespace Bit.Droid.Renderers holder.TextView.SetTextColor(_boxedView.FooterTextColor.ToAndroid()); } - //update text + // Update text holder.TextView.Text = formsCell.Text; } @@ -305,31 +298,31 @@ namespace Bit.Droid.Renderers var minHeight = (int)Math.Max(_context.ToPixels(_boxedView.RowHeight), MinRowHeight); - //it is neccesary to set both + // It is necessary to set both layout.SetMinimumHeight(minHeight); nativeCell.SetMinimumHeight(minHeight); if(!_boxedView.HasUnevenRows) { - // if not Uneven, set the larger one of RowHeight and MinRowHeight. + // If not Uneven, set the larger one of RowHeight and MinRowHeight. layout.LayoutParameters.Height = minHeight; } else if(formsCell.Height > -1) { - // if the cell itself was specified height, set it. + // If the cell itself was specified height, set it. layout.SetMinimumHeight((int)_context.ToPixels(formsCell.Height)); layout.LayoutParameters.Height = (int)_context.ToPixels(formsCell.Height); } else if(formsCell is ViewCell viewCell) { - // if used a viewcell, calculate the size and layout it. + // If used a viewcell, calculate the size and layout it. var size = viewCell.View.Measure(_boxedView.Width, double.PositiveInfinity); viewCell.View.Layout(new Rectangle(0, 0, size.Request.Width, size.Request.Height)); layout.LayoutParameters.Height = (int)_context.ToPixels(size.Request.Height); } else { - layout.LayoutParameters.Height = -2; //wrap_content + layout.LayoutParameters.Height = -2; // wrap_content } if(!CellCaches[position].IsLastCell || _boxedView.ShowSectionTopBottomBorder) @@ -446,7 +439,7 @@ namespace Bit.Droid.Renderers [Preserve(AllMembers = true)] internal class HeaderViewHolder : ViewHolder { - public HeaderViewHolder(AView view, BoxedView boxedView) + public HeaderViewHolder(AView view, App.Controls.BoxedView.BoxedView boxedView) : base(view) { TextView = view.FindViewById(Resource.Id.HeaderCellText); @@ -474,7 +467,7 @@ namespace Bit.Droid.Renderers { public TextView TextView { get; private set; } - public FooterViewHolder(AView view, BoxedView boxedView) + public FooterViewHolder(AView view, App.Controls.BoxedView.BoxedView boxedView) : base(view) { TextView = view.FindViewById(Resource.Id.FooterCellText); diff --git a/src/Android/Renderers/BoxedView/BoxedViewRenderer.cs b/src/Android/Renderers/BoxedView/BoxedViewRenderer.cs index 6842682ac..d13f11bdd 100644 --- a/src/Android/Renderers/BoxedView/BoxedViewRenderer.cs +++ b/src/Android/Renderers/BoxedView/BoxedViewRenderer.cs @@ -4,17 +4,17 @@ using Android.Support.V7.Widget; using Android.Support.V7.Widget.Helper; using Android.Views; using Bit.App.Controls.BoxedView; -using Bit.Droid.Renderers; +using Bit.Droid.Renderers.BoxedView; using System; using System.ComponentModel; using Xamarin.Forms; using Xamarin.Forms.Platform.Android; [assembly: ExportRenderer(typeof(BoxedView), typeof(BoxedViewRenderer))] -namespace Bit.Droid.Renderers +namespace Bit.Droid.Renderers.BoxedView { [Preserve(AllMembers = true)] - public class BoxedViewRenderer : ViewRenderer + public class BoxedViewRenderer : ViewRenderer { private Page _parentPage; private LinearLayoutManager _layoutManager; @@ -28,7 +28,7 @@ namespace Bit.Droid.Renderers AutoPackage = false; } - protected override void OnElementChanged(ElementChangedEventArgs e) + protected override void OnElementChanged(ElementChangedEventArgs e) { base.OnElementChanged(e); if(e.NewElement != null) @@ -48,7 +48,8 @@ namespace Bit.Droid.Renderers _adapter = new BoxedViewRecyclerAdapter(Context, e.NewElement, recyclerView); Control.SetAdapter(_adapter); - _simpleCallback = new BoxedViewSimpleCallback(e.NewElement, ItemTouchHelper.Up | ItemTouchHelper.Down, 0); + _simpleCallback = new BoxedViewSimpleCallback( + e.NewElement, ItemTouchHelper.Up | ItemTouchHelper.Down, 0); _itemTouchhelper = new ItemTouchHelper(_simpleCallback); _itemTouchhelper.AttachToRecyclerView(Control); @@ -100,11 +101,11 @@ namespace Bit.Droid.Renderers protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e) { base.OnElementPropertyChanged(sender, e); - if(e.PropertyName == BoxedView.SeparatorColorProperty.PropertyName) + if(e.PropertyName == App.Controls.BoxedView.BoxedView.SeparatorColorProperty.PropertyName) { _adapter.NotifyDataSetChanged(); } - else if(e.PropertyName == BoxedView.BackgroundColorProperty.PropertyName) + else if(e.PropertyName == App.Controls.BoxedView.BoxedView.BackgroundColorProperty.PropertyName) { UpdateBackgroundColor(); } @@ -112,11 +113,11 @@ namespace Bit.Droid.Renderers { UpdateRowHeight(); } - else if(e.PropertyName == BoxedView.SelectedColorProperty.PropertyName) + else if(e.PropertyName == App.Controls.BoxedView.BoxedView.SelectedColorProperty.PropertyName) { //_adapter.NotifyDataSetChanged(); } - else if(e.PropertyName == BoxedView.ShowSectionTopBottomBorderProperty.PropertyName) + else if(e.PropertyName == App.Controls.BoxedView.BoxedView.ShowSectionTopBottomBorderProperty.PropertyName) { _adapter.NotifyDataSetChanged(); } @@ -124,11 +125,11 @@ namespace Bit.Droid.Renderers { _adapter.NotifyDataSetChanged(); } - else if(e.PropertyName == BoxedView.ScrollToTopProperty.PropertyName) + else if(e.PropertyName == App.Controls.BoxedView.BoxedView.ScrollToTopProperty.PropertyName) { UpdateScrollToTop(); } - else if(e.PropertyName == BoxedView.ScrollToBottomProperty.PropertyName) + else if(e.PropertyName == App.Controls.BoxedView.BoxedView.ScrollToBottomProperty.PropertyName) { UpdateScrollToBottom(); } diff --git a/src/Android/Renderers/BoxedView/BoxedViewSimpleCallback.cs b/src/Android/Renderers/BoxedView/BoxedViewSimpleCallback.cs index d505e18d9..e94f7ed06 100644 --- a/src/Android/Renderers/BoxedView/BoxedViewSimpleCallback.cs +++ b/src/Android/Renderers/BoxedView/BoxedViewSimpleCallback.cs @@ -1,24 +1,24 @@ using Android.Runtime; using Android.Support.V7.Widget; using Android.Support.V7.Widget.Helper; -using Bit.App.Controls.BoxedView; using System; -namespace Bit.Droid.Renderers +namespace Bit.Droid.Renderers.BoxedView { [Preserve(AllMembers = true)] public class BoxedViewSimpleCallback : ItemTouchHelper.SimpleCallback { - private BoxedView _boxedView; + private App.Controls.BoxedView.BoxedView _boxedView; private int _offset = 0; - public BoxedViewSimpleCallback(BoxedView boxedView, int dragDirs, int swipeDirs) + public BoxedViewSimpleCallback(App.Controls.BoxedView.BoxedView boxedView, int dragDirs, int swipeDirs) : base(dragDirs, swipeDirs) { _boxedView = boxedView; } - public override bool OnMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) + public override bool OnMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, + RecyclerView.ViewHolder target) { if(!(viewHolder is ContentViewHolder fromContentHolder)) { diff --git a/src/Android/Renderers/BoxedView/Cells/BaseCellRenderer.cs b/src/Android/Renderers/BoxedView/Cells/BaseCellRenderer.cs index 2b92bddc6..f97fa31ff 100644 --- a/src/Android/Renderers/BoxedView/Cells/BaseCellRenderer.cs +++ b/src/Android/Renderers/BoxedView/Cells/BaseCellRenderer.cs @@ -8,26 +8,11 @@ using System.Linq.Expressions; using System.Reflection; using Xamarin.Forms.Platform.Android; -namespace Bit.Droid.Renderers +namespace Bit.Droid.Renderers.BoxedView { [Preserve(AllMembers = true)] public class BaseCellRenderer : CellRenderer where TNativeCell : BaseCellView { - internal static class InstanceCreator - { - public static Func Create { get; } = CreateInstance(); - - private static Func CreateInstance() - { - var argsTypes = new[] { typeof(T1), typeof(T2) }; - var constructor = typeof(TInstance).GetConstructor( - BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, - Type.DefaultBinder, argsTypes, null); - var args = argsTypes.Select(Expression.Parameter).ToArray(); - return Expression.Lambda>(Expression.New(constructor, args), args).Compile(); - } - } - protected override View GetCellCore(Xamarin.Forms.Cell item, View convertView, ViewGroup parent, Context context) { @@ -47,7 +32,7 @@ namespace Bit.Droid.Renderers { var formsCell = nativeCell.Cell as BaseCell; formsCell.PropertyChanged += nativeCell.CellPropertyChanged; - if(formsCell.Parent is BoxedView parentElement) + if(formsCell.Parent is App.Controls.BoxedView.BoxedView parentElement) { parentElement.PropertyChanged += nativeCell.ParentPropertyChanged; var section = parentElement.Model.GetSection(BoxedModel.GetPath(formsCell).Item1); @@ -63,7 +48,7 @@ namespace Bit.Droid.Renderers { var formsCell = nativeCell.Cell as BaseCell; formsCell.PropertyChanged -= nativeCell.CellPropertyChanged; - if(formsCell.Parent is BoxedView parentElement) + if(formsCell.Parent is App.Controls.BoxedView.BoxedView parentElement) { parentElement.PropertyChanged -= nativeCell.ParentPropertyChanged; if(formsCell.Section != null) @@ -72,5 +57,20 @@ namespace Bit.Droid.Renderers } } } + + internal static class InstanceCreator + { + public static Func Create { get; } = CreateInstance(); + + private static Func CreateInstance() + { + var argsTypes = new[] { typeof(T1), typeof(T2) }; + var constructor = typeof(TInstance).GetConstructor( + BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, + Type.DefaultBinder, argsTypes, null); + var args = argsTypes.Select(Expression.Parameter).ToArray(); + return Expression.Lambda>(Expression.New(constructor, args), args).Compile(); + } + } } } diff --git a/src/Android/Renderers/BoxedView/Cells/BaseCellView.cs b/src/Android/Renderers/BoxedView/Cells/BaseCellView.cs index e35d6f943..ede1e27b8 100644 --- a/src/Android/Renderers/BoxedView/Cells/BaseCellView.cs +++ b/src/Android/Renderers/BoxedView/Cells/BaseCellView.cs @@ -12,7 +12,7 @@ using Xamarin.Forms; using Xamarin.Forms.Platform.Android; using ARelativeLayout = Android.Widget.RelativeLayout; -namespace Bit.Droid.Renderers +namespace Bit.Droid.Renderers.BoxedView { [Preserve(AllMembers = true)] public class BaseCellView : ARelativeLayout, INativeElementView @@ -37,7 +37,7 @@ namespace Bit.Droid.Renderers public Cell Cell { get; set; } public Element Element => Cell; protected BaseCell CellBase => Cell as BaseCell; - public BoxedView CellParent => Cell.Parent as BoxedView; + public App.Controls.BoxedView.BoxedView CellParent => Cell.Parent as App.Controls.BoxedView.BoxedView; public TextView TitleLabel { get; set; } public TextView DescriptionLabel { get; set; } public LinearLayout ContentStack { get; set; } @@ -122,27 +122,27 @@ namespace Bit.Droid.Renderers return; } - if(e.PropertyName == BoxedView.CellTitleColorProperty.PropertyName) + if(e.PropertyName == App.Controls.BoxedView.BoxedView.CellTitleColorProperty.PropertyName) { UpdateTitleColor(); } - else if(e.PropertyName == BoxedView.CellTitleFontSizeProperty.PropertyName) + else if(e.PropertyName == App.Controls.BoxedView.BoxedView.CellTitleFontSizeProperty.PropertyName) { UpdateWithForceLayout(UpdateTitleFontSize); } - else if(e.PropertyName == BoxedView.CellDescriptionColorProperty.PropertyName) + else if(e.PropertyName == App.Controls.BoxedView.BoxedView.CellDescriptionColorProperty.PropertyName) { UpdateDescriptionColor(); } - else if(e.PropertyName == BoxedView.CellDescriptionFontSizeProperty.PropertyName) + else if(e.PropertyName == App.Controls.BoxedView.BoxedView.CellDescriptionFontSizeProperty.PropertyName) { UpdateWithForceLayout(UpdateDescriptionFontSize); } - else if(e.PropertyName == BoxedView.CellBackgroundColorProperty.PropertyName) + else if(e.PropertyName == App.Controls.BoxedView.BoxedView.CellBackgroundColorProperty.PropertyName) { UpdateBackgroundColor(); } - else if(e.PropertyName == BoxedView.SelectedColorProperty.PropertyName) + else if(e.PropertyName == App.Controls.BoxedView.BoxedView.SelectedColorProperty.PropertyName) { UpdateWithForceLayout(UpdateSelectedColor); } diff --git a/src/Android/Renderers/BoxedView/Cells/LabelCellRenderer.cs b/src/Android/Renderers/BoxedView/Cells/LabelCellRenderer.cs index 7428d093c..083f80b63 100644 --- a/src/Android/Renderers/BoxedView/Cells/LabelCellRenderer.cs +++ b/src/Android/Renderers/BoxedView/Cells/LabelCellRenderer.cs @@ -4,13 +4,13 @@ using Android.Text; using Android.Views; using Android.Widget; using Bit.App.Controls.BoxedView; -using Bit.Droid.Renderers; +using Bit.Droid.Renderers.BoxedView; using System.ComponentModel; using Xamarin.Forms; using Xamarin.Forms.Platform.Android; [assembly: ExportRenderer(typeof(LabelCell), typeof(LabelCellRenderer))] -namespace Bit.Droid.Renderers +namespace Bit.Droid.Renderers.BoxedView { [Preserve(AllMembers = true)] public class LabelCellRenderer : BaseCellRenderer @@ -59,11 +59,11 @@ namespace Bit.Droid.Renderers public override void ParentPropertyChanged(object sender, PropertyChangedEventArgs e) { base.ParentPropertyChanged(sender, e); - if(e.PropertyName == BoxedView.CellValueTextColorProperty.PropertyName) + if(e.PropertyName == App.Controls.BoxedView.BoxedView.CellValueTextColorProperty.PropertyName) { UpdateValueTextColor(); } - else if(e.PropertyName == BoxedView.CellValueTextFontSizeProperty.PropertyName) + else if(e.PropertyName == App.Controls.BoxedView.BoxedView.CellValueTextFontSizeProperty.PropertyName) { UpdateValueTextFontSize(); } diff --git a/src/App/Controls/BoxedView/BoxedView.cs b/src/App/Controls/BoxedView/BoxedView.cs index 8fd14d4bf..7fb540d7b 100644 --- a/src/App/Controls/BoxedView/BoxedView.cs +++ b/src/App/Controls/BoxedView/BoxedView.cs @@ -9,9 +9,117 @@ namespace Bit.App.Controls.BoxedView [ContentProperty("Root")] public class BoxedView : TableView { - private BoxedRoot _root; + public static new BindableProperty BackgroundColorProperty = BindableProperty.Create( + nameof(BackgroundColor), typeof(Color), typeof(BoxedView), default(Color), + defaultBindingMode: BindingMode.OneWay); - public new event EventHandler ModelChanged; + public static BindableProperty SeparatorColorProperty = BindableProperty.Create( + nameof(SeparatorColor), typeof(Color), typeof(BoxedView), Color.FromRgb(199, 199, 204), + defaultBindingMode: BindingMode.OneWay); + + public static BindableProperty SelectedColorProperty = BindableProperty.Create( + nameof(SelectedColor), typeof(Color), typeof(BoxedView), default(Color), + defaultBindingMode: BindingMode.OneWay); + + public static BindableProperty HeaderPaddingProperty = BindableProperty.Create( + nameof(HeaderPadding), typeof(Thickness), typeof(BoxedView), new Thickness(14, 8, 8, 8), + defaultBindingMode: BindingMode.OneWay); + + public static BindableProperty HeaderTextColorProperty = BindableProperty.Create( + nameof(HeaderTextColor), typeof(Color), typeof(BoxedView), default(Color), + defaultBindingMode: BindingMode.OneWay); + + public static BindableProperty HeaderFontSizeProperty = BindableProperty.Create( + nameof(HeaderFontSize), typeof(double), typeof(BoxedView), -1.0d, + defaultBindingMode: BindingMode.OneWay, + defaultValueCreator: bindable => Device.GetNamedSize(NamedSize.Small, (BoxedView)bindable)); + + public static BindableProperty HeaderTextVerticalAlignProperty = BindableProperty.Create( + nameof(HeaderTextVerticalAlign), typeof(LayoutAlignment), typeof(BoxedView), LayoutAlignment.End, + defaultBindingMode: BindingMode.OneWay); + + public static BindableProperty HeaderBackgroundColorProperty = BindableProperty.Create( + nameof(HeaderBackgroundColor), typeof(Color), typeof(BoxedView), default(Color), + defaultBindingMode: BindingMode.OneWay); + + public static BindableProperty HeaderHeightProperty = BindableProperty.Create( + nameof(HeaderHeight), typeof(double), typeof(BoxedView), -1d, defaultBindingMode: BindingMode.OneWay); + + public static BindableProperty FooterTextColorProperty = BindableProperty.Create( + nameof(FooterTextColor), typeof(Color), typeof(BoxedView), default(Color), + defaultBindingMode: BindingMode.OneWay); + + public static BindableProperty FooterFontSizeProperty = BindableProperty.Create( + nameof(FooterFontSize), typeof(double), typeof(BoxedView), -1.0d, + defaultBindingMode: BindingMode.OneWay, + defaultValueCreator: bindable => Device.GetNamedSize(NamedSize.Small, (BoxedView)bindable)); + + public static BindableProperty FooterBackgroundColorProperty = BindableProperty.Create( + nameof(FooterBackgroundColor), typeof(Color), typeof(BoxedView), default(Color), + defaultBindingMode: BindingMode.OneWay); + + public static BindableProperty FooterPaddingProperty = BindableProperty.Create( + nameof(FooterPadding), typeof(Thickness), typeof(BoxedView), new Thickness(14, 8, 14, 8), + defaultBindingMode: BindingMode.OneWay); + + public static BindableProperty CellTitleColorProperty = BindableProperty.Create( + nameof(CellTitleColor), typeof(Color), typeof(BoxedView), default(Color), + defaultBindingMode: BindingMode.OneWay); + + public static BindableProperty CellTitleFontSizeProperty = BindableProperty.Create( + nameof(CellTitleFontSize), typeof(double), typeof(BoxedView), -1.0, + defaultBindingMode: BindingMode.OneWay, + defaultValueCreator: bindable => Device.GetNamedSize(NamedSize.Default, (BoxedView)bindable)); + + public static BindableProperty CellValueTextColorProperty = BindableProperty.Create( + nameof(CellValueTextColor), typeof(Color), typeof(BoxedView), default(Color), + defaultBindingMode: BindingMode.OneWay); + + public static BindableProperty CellValueTextFontSizeProperty = BindableProperty.Create( + nameof(CellValueTextFontSize), typeof(double), typeof(BoxedView), -1.0d, + defaultBindingMode: BindingMode.OneWay); + + public static BindableProperty CellDescriptionColorProperty = BindableProperty.Create( + nameof(CellDescriptionColor), typeof(Color), typeof(BoxedView), default(Color), + defaultBindingMode: BindingMode.OneWay); + + public static BindableProperty CellDescriptionFontSizeProperty = BindableProperty.Create( + nameof(CellDescriptionFontSize), typeof(double), typeof(BoxedView), -1.0d, + defaultBindingMode: BindingMode.OneWay); + + public static BindableProperty CellBackgroundColorProperty = BindableProperty.Create( + nameof(CellBackgroundColor), typeof(Color), typeof(BoxedView), default(Color), + defaultBindingMode: BindingMode.OneWay); + + public static BindableProperty CellAccentColorProperty = BindableProperty.Create( + nameof(CellAccentColor), typeof(Color), typeof(BoxedView), Color.Accent, + defaultBindingMode: BindingMode.OneWay); + + public static BindableProperty ShowSectionTopBottomBorderProperty = BindableProperty.Create( + nameof(ShowSectionTopBottomBorder), typeof(bool), typeof(BoxedView), true, + defaultBindingMode: BindingMode.OneWay); + + public static BindableProperty ScrollToBottomProperty = BindableProperty.Create( + nameof(ScrollToBottom), typeof(bool), typeof(BoxedView), default(bool), + defaultBindingMode: BindingMode.TwoWay); + + public static BindableProperty ScrollToTopProperty = BindableProperty.Create( + nameof(ScrollToTop), typeof(bool), typeof(BoxedView), default(bool), + defaultBindingMode: BindingMode.TwoWay); + + public static BindableProperty VisibleContentHeightProperty = BindableProperty.Create( + nameof(VisibleContentHeight), typeof(double), typeof(BoxedView), -1d, + defaultBindingMode: BindingMode.OneWayToSource); + + public static BindableProperty ItemsSourceProperty = BindableProperty.Create( + nameof(ItemsSource), typeof(IEnumerable), typeof(BoxedView), default(IEnumerable), + defaultBindingMode: BindingMode.OneWay, propertyChanged: ItemsChanged); + + public static BindableProperty ItemTemplateProperty = BindableProperty.Create( + nameof(ItemTemplate), typeof(DataTemplate), typeof(BoxedView), default(DataTemplate), + defaultBindingMode: BindingMode.OneWay); + + private BoxedRoot _root; public BoxedView() { @@ -45,6 +153,178 @@ namespace Bit.App.Controls.BoxedView } } + // Make the unnecessary property existing at TableView sealed. + private new int Intent { get; set; } + + public new Color BackgroundColor + { + get => (Color)GetValue(BackgroundColorProperty); + set => SetValue(BackgroundColorProperty, value); + } + + public Color SeparatorColor + { + get => (Color)GetValue(SeparatorColorProperty); + set => SetValue(SeparatorColorProperty, value); + } + + public Color SelectedColor + { + get => (Color)GetValue(SelectedColorProperty); + set => SetValue(SelectedColorProperty, value); + } + + public Thickness HeaderPadding + { + get => (Thickness)GetValue(HeaderPaddingProperty); + set => SetValue(HeaderPaddingProperty, value); + } + + public Color HeaderTextColor + { + get => (Color)GetValue(HeaderTextColorProperty); + set => SetValue(HeaderTextColorProperty, value); + } + + [TypeConverter(typeof(FontSizeConverter))] + public double HeaderFontSize + { + get => (double)GetValue(HeaderFontSizeProperty); + set => SetValue(HeaderFontSizeProperty, value); + } + + public LayoutAlignment HeaderTextVerticalAlign + { + get => (LayoutAlignment)GetValue(HeaderTextVerticalAlignProperty); + set => SetValue(HeaderTextVerticalAlignProperty, value); + } + + public Color HeaderBackgroundColor + { + get => (Color)GetValue(HeaderBackgroundColorProperty); + set => SetValue(HeaderBackgroundColorProperty, value); + } + + public double HeaderHeight + { + get => (double)GetValue(HeaderHeightProperty); + set => SetValue(HeaderHeightProperty, value); + } + + public Color FooterTextColor + { + get => (Color)GetValue(FooterTextColorProperty); + set => SetValue(FooterTextColorProperty, value); + } + + [TypeConverter(typeof(FontSizeConverter))] + public double FooterFontSize + { + get => (double)GetValue(FooterFontSizeProperty); + set => SetValue(FooterFontSizeProperty, value); + } + + public Color FooterBackgroundColor + { + get => (Color)GetValue(FooterBackgroundColorProperty); + set => SetValue(FooterBackgroundColorProperty, value); + } + + public Thickness FooterPadding + { + get => (Thickness)GetValue(FooterPaddingProperty); + set => SetValue(FooterPaddingProperty, value); + } + + public Color CellTitleColor + { + get => (Color)GetValue(CellTitleColorProperty); + set => SetValue(CellTitleColorProperty, value); + } + + [TypeConverter(typeof(FontSizeConverter))] + public double CellTitleFontSize + { + get => (double)GetValue(CellTitleFontSizeProperty); + set => SetValue(CellTitleFontSizeProperty, value); + } + + public Color CellValueTextColor + { + get => (Color)GetValue(CellValueTextColorProperty); + set => SetValue(CellValueTextColorProperty, value); + } + + [TypeConverter(typeof(FontSizeConverter))] + public double CellValueTextFontSize + { + get => (double)GetValue(CellValueTextFontSizeProperty); + set => SetValue(CellValueTextFontSizeProperty, value); + } + + public Color CellDescriptionColor + { + get => (Color)GetValue(CellDescriptionColorProperty); + set => SetValue(CellDescriptionColorProperty, value); + } + + [TypeConverter(typeof(FontSizeConverter))] + public double CellDescriptionFontSize + { + get => (double)GetValue(CellDescriptionFontSizeProperty); + set => SetValue(CellDescriptionFontSizeProperty, value); + } + + public Color CellBackgroundColor + { + get => (Color)GetValue(CellBackgroundColorProperty); + set => SetValue(CellBackgroundColorProperty, value); + } + + public Color CellAccentColor + { + get => (Color)GetValue(CellAccentColorProperty); + set => SetValue(CellAccentColorProperty, value); + } + + public bool ShowSectionTopBottomBorder + { + get => (bool)GetValue(ShowSectionTopBottomBorderProperty); + set => SetValue(ShowSectionTopBottomBorderProperty, value); + } + + public bool ScrollToBottom + { + get => (bool)GetValue(ScrollToBottomProperty); + set => SetValue(ScrollToBottomProperty, value); + } + + public bool ScrollToTop + { + get => (bool)GetValue(ScrollToTopProperty); + set => SetValue(ScrollToTopProperty, value); + } + + public double VisibleContentHeight + { + get => (double)GetValue(VisibleContentHeightProperty); + set => SetValue(VisibleContentHeightProperty, value); + } + + public IEnumerable ItemsSource + { + get => (IEnumerable)GetValue(ItemsSourceProperty); + set => SetValue(ItemsSourceProperty, value); + } + + public DataTemplate ItemTemplate + { + get => (DataTemplate)GetValue(ItemTemplateProperty); + set => SetValue(ItemTemplateProperty, value); + } + + public new event EventHandler ModelChanged; + protected override void OnBindingContextChanged() { base.OnBindingContextChanged(); @@ -56,9 +336,10 @@ namespace Bit.App.Controls.BoxedView private void RootOnPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) { - if(e.PropertyName == TableSectionBase.TitleProperty.PropertyName || + var changed = e.PropertyName == TableSectionBase.TitleProperty.PropertyName || e.PropertyName == BoxedSection.FooterTextProperty.PropertyName || - e.PropertyName == BoxedSection.IsVisibleProperty.PropertyName) + e.PropertyName == BoxedSection.IsVisibleProperty.PropertyName; + if(changed) { OnModelChanged(); } @@ -108,424 +389,6 @@ namespace Bit.App.Controls.BoxedView ModelChanged?.Invoke(this, EventArgs.Empty); } - // Make the unnecessary property existing at TableView sealed. - private new int Intent { get; set; } - - public static new BindableProperty BackgroundColorProperty = - BindableProperty.Create( - nameof(BackgroundColor), - typeof(Color), - typeof(BoxedView), - default(Color), - defaultBindingMode: BindingMode.OneWay - ); - - public new Color BackgroundColor - { - get { return (Color)GetValue(BackgroundColorProperty); } - set { SetValue(BackgroundColorProperty, value); } - } - - public static BindableProperty SeparatorColorProperty = - BindableProperty.Create( - nameof(SeparatorColor), - typeof(Color), - typeof(BoxedView), - Color.FromRgb(199, 199, 204), - defaultBindingMode: BindingMode.OneWay - ); - - public Color SeparatorColor - { - get { return (Color)GetValue(SeparatorColorProperty); } - set { SetValue(SeparatorColorProperty, value); } - } - - public static BindableProperty SelectedColorProperty = - BindableProperty.Create( - nameof(SelectedColor), - typeof(Color), - typeof(BoxedView), - default(Color), - defaultBindingMode: BindingMode.OneWay - ); - - public Color SelectedColor - { - get { return (Color)GetValue(SelectedColorProperty); } - set { SetValue(SelectedColorProperty, value); } - } - - public static BindableProperty HeaderPaddingProperty = - BindableProperty.Create( - nameof(HeaderPadding), - typeof(Thickness), - typeof(BoxedView), - new Thickness(14, 8, 8, 8), - defaultBindingMode: BindingMode.OneWay - ); - - public Thickness HeaderPadding - { - get { return (Thickness)GetValue(HeaderPaddingProperty); } - set { SetValue(HeaderPaddingProperty, value); } - } - - public static BindableProperty HeaderTextColorProperty = - BindableProperty.Create( - nameof(HeaderTextColor), - typeof(Color), - typeof(BoxedView), - default(Color), - defaultBindingMode: BindingMode.OneWay - ); - - public Color HeaderTextColor - { - get { return (Color)GetValue(HeaderTextColorProperty); } - set { SetValue(HeaderTextColorProperty, value); } - } - - public static BindableProperty HeaderFontSizeProperty = - BindableProperty.Create( - nameof(HeaderFontSize), - typeof(double), - typeof(BoxedView), - -1.0d, - defaultBindingMode: BindingMode.OneWay, - defaultValueCreator: bindable => Device.GetNamedSize(NamedSize.Small, (BoxedView)bindable) - ); - - [TypeConverter(typeof(FontSizeConverter))] - public double HeaderFontSize - { - get { return (double)GetValue(HeaderFontSizeProperty); } - set { SetValue(HeaderFontSizeProperty, value); } - } - - public static BindableProperty HeaderTextVerticalAlignProperty = - BindableProperty.Create( - nameof(HeaderTextVerticalAlign), - typeof(LayoutAlignment), - typeof(BoxedView), - LayoutAlignment.End, - defaultBindingMode: BindingMode.OneWay - ); - - public LayoutAlignment HeaderTextVerticalAlign - { - get { return (LayoutAlignment)GetValue(HeaderTextVerticalAlignProperty); } - set { SetValue(HeaderTextVerticalAlignProperty, value); } - } - - public static BindableProperty HeaderBackgroundColorProperty = - BindableProperty.Create( - nameof(HeaderBackgroundColor), - typeof(Color), - typeof(BoxedView), - default(Color), - defaultBindingMode: BindingMode.OneWay - ); - - public Color HeaderBackgroundColor - { - get { return (Color)GetValue(HeaderBackgroundColorProperty); } - set { SetValue(HeaderBackgroundColorProperty, value); } - } - - public static BindableProperty HeaderHeightProperty = - BindableProperty.Create( - nameof(HeaderHeight), - typeof(double), - typeof(BoxedView), - -1d, - defaultBindingMode: BindingMode.OneWay - ); - - public double HeaderHeight - { - get { return (double)GetValue(HeaderHeightProperty); } - set { SetValue(HeaderHeightProperty, value); } - } - - public static BindableProperty FooterTextColorProperty = - BindableProperty.Create( - nameof(FooterTextColor), - typeof(Color), - typeof(BoxedView), - default(Color), - defaultBindingMode: BindingMode.OneWay - ); - - public Color FooterTextColor - { - get { return (Color)GetValue(FooterTextColorProperty); } - set { SetValue(FooterTextColorProperty, value); } - } - - public static BindableProperty FooterFontSizeProperty = - BindableProperty.Create( - nameof(FooterFontSize), - typeof(double), - typeof(BoxedView), - -1.0d, - defaultBindingMode: BindingMode.OneWay, - defaultValueCreator: bindable => Device.GetNamedSize(NamedSize.Small, (BoxedView)bindable) - ); - - [TypeConverter(typeof(FontSizeConverter))] - public double FooterFontSize - { - get { return (double)GetValue(FooterFontSizeProperty); } - set { SetValue(FooterFontSizeProperty, value); } - } - - public static BindableProperty FooterBackgroundColorProperty = - BindableProperty.Create( - nameof(FooterBackgroundColor), - typeof(Color), - typeof(BoxedView), - default(Color), - defaultBindingMode: BindingMode.OneWay - ); - - public Color FooterBackgroundColor - { - get { return (Color)GetValue(FooterBackgroundColorProperty); } - set { SetValue(FooterBackgroundColorProperty, value); } - } - - public static BindableProperty FooterPaddingProperty = - BindableProperty.Create( - nameof(FooterPadding), - typeof(Thickness), - typeof(BoxedView), - new Thickness(14, 8, 14, 8), - defaultBindingMode: BindingMode.OneWay - ); - - public Thickness FooterPadding - { - get { return (Thickness)GetValue(FooterPaddingProperty); } - set { SetValue(FooterPaddingProperty, value); } - } - - public static BindableProperty CellTitleColorProperty = - BindableProperty.Create( - nameof(CellTitleColor), - typeof(Color), - typeof(BoxedView), - default(Color), - defaultBindingMode: BindingMode.OneWay - ); - - public Color CellTitleColor - { - get { return (Color)GetValue(CellTitleColorProperty); } - set { SetValue(CellTitleColorProperty, value); } - } - - public static BindableProperty CellTitleFontSizeProperty = - BindableProperty.Create( - nameof(CellTitleFontSize), - typeof(double), - typeof(BoxedView), - -1.0, - defaultBindingMode: BindingMode.OneWay, - defaultValueCreator: bindable => Device.GetNamedSize(NamedSize.Default, (BoxedView)bindable) - ); - - - [TypeConverter(typeof(FontSizeConverter))] - public double CellTitleFontSize - { - get { return (double)GetValue(CellTitleFontSizeProperty); } - set { SetValue(CellTitleFontSizeProperty, value); } - } - - public static BindableProperty CellValueTextColorProperty = - BindableProperty.Create( - nameof(CellValueTextColor), - typeof(Color), - typeof(BoxedView), - default(Color), - defaultBindingMode: BindingMode.OneWay - ); - - public Color CellValueTextColor - { - get { return (Color)GetValue(CellValueTextColorProperty); } - set { SetValue(CellValueTextColorProperty, value); } - } - - public static BindableProperty CellValueTextFontSizeProperty = - BindableProperty.Create( - nameof(CellValueTextFontSize), - typeof(double), - typeof(BoxedView), - -1.0d, - defaultBindingMode: BindingMode.OneWay - ); - - [TypeConverter(typeof(FontSizeConverter))] - public double CellValueTextFontSize - { - get { return (double)GetValue(CellValueTextFontSizeProperty); } - set { SetValue(CellValueTextFontSizeProperty, value); } - } - - public static BindableProperty CellDescriptionColorProperty = - BindableProperty.Create( - nameof(CellDescriptionColor), - typeof(Color), - typeof(BoxedView), - default(Color), - defaultBindingMode: BindingMode.OneWay - ); - - public Color CellDescriptionColor - { - get { return (Color)GetValue(CellDescriptionColorProperty); } - set { SetValue(CellDescriptionColorProperty, value); } - } - - public static BindableProperty CellDescriptionFontSizeProperty = - BindableProperty.Create( - nameof(CellDescriptionFontSize), - typeof(double), - typeof(BoxedView), - -1.0d, - defaultBindingMode: BindingMode.OneWay - ); - - [TypeConverter(typeof(FontSizeConverter))] - public double CellDescriptionFontSize - { - get { return (double)GetValue(CellDescriptionFontSizeProperty); } - set { SetValue(CellDescriptionFontSizeProperty, value); } - } - - public static BindableProperty CellBackgroundColorProperty = - BindableProperty.Create( - nameof(CellBackgroundColor), - typeof(Color), - typeof(BoxedView), - default(Color), - defaultBindingMode: BindingMode.OneWay - ); - - public Color CellBackgroundColor - { - get { return (Color)GetValue(CellBackgroundColorProperty); } - set { SetValue(CellBackgroundColorProperty, value); } - } - - public static BindableProperty CellAccentColorProperty = - BindableProperty.Create( - nameof(CellAccentColor), - typeof(Color), - typeof(BoxedView), - Color.Accent, - defaultBindingMode: BindingMode.OneWay - ); - - public Color CellAccentColor - { - get { return (Color)GetValue(CellAccentColorProperty); } - set { SetValue(CellAccentColorProperty, value); } - } - - public static BindableProperty ShowSectionTopBottomBorderProperty = - BindableProperty.Create( - nameof(ShowSectionTopBottomBorder), - typeof(bool), - typeof(BoxedView), - true, - defaultBindingMode: BindingMode.OneWay - ); - - public bool ShowSectionTopBottomBorder - { - get { return (bool)GetValue(ShowSectionTopBottomBorderProperty); } - set { SetValue(ShowSectionTopBottomBorderProperty, value); } - } - - public static BindableProperty ScrollToBottomProperty = - BindableProperty.Create( - nameof(ScrollToBottom), - typeof(bool), - typeof(BoxedView), - default(bool), - defaultBindingMode: BindingMode.TwoWay - ); - - public bool ScrollToBottom - { - get { return (bool)GetValue(ScrollToBottomProperty); } - set { SetValue(ScrollToBottomProperty, value); } - } - - public static BindableProperty ScrollToTopProperty = - BindableProperty.Create( - nameof(ScrollToTop), - typeof(bool), - typeof(BoxedView), - default(bool), - defaultBindingMode: BindingMode.TwoWay - ); - - public bool ScrollToTop - { - get { return (bool)GetValue(ScrollToTopProperty); } - set { SetValue(ScrollToTopProperty, value); } - } - - public static BindableProperty VisibleContentHeightProperty = - BindableProperty.Create( - nameof(VisibleContentHeight), - typeof(double), - typeof(BoxedView), - -1d, - defaultBindingMode: BindingMode.OneWayToSource - ); - - public double VisibleContentHeight - { - get { return (double)GetValue(VisibleContentHeightProperty); } - set { SetValue(VisibleContentHeightProperty, value); } - } - - public static BindableProperty ItemsSourceProperty = - BindableProperty.Create( - nameof(ItemsSource), - typeof(IEnumerable), - typeof(BoxedView), - default(IEnumerable), - defaultBindingMode: BindingMode.OneWay, - propertyChanged: ItemsChanged - ); - - public IEnumerable ItemsSource - { - get { return (IEnumerable)GetValue(ItemsSourceProperty); } - set { SetValue(ItemsSourceProperty, value); } - } - - public static BindableProperty ItemTemplateProperty = - BindableProperty.Create( - nameof(ItemTemplate), - typeof(DataTemplate), - typeof(BoxedView), - default(DataTemplate), - defaultBindingMode: BindingMode.OneWay - ); - - public DataTemplate ItemTemplate - { - get { return (DataTemplate)GetValue(ItemTemplateProperty); } - set { SetValue(ItemTemplateProperty, value); } - } - private static void ItemsChanged(BindableObject bindable, object oldValue, object newValue) { var boxedView = bindable as BoxedView; @@ -542,7 +405,6 @@ namespace Bit.App.Controls.BoxedView { newObservableCollection.CollectionChanged += boxedView.OnItemsSourceCollectionChanged; } - boxedView.Root.Clear(); if(newValue is IList newValueAsEnumerable) diff --git a/src/App/Controls/BoxedView/Cells/BaseCell.cs b/src/App/Controls/BoxedView/Cells/BaseCell.cs index 7a9bde8e2..b78f782ba 100644 --- a/src/App/Controls/BoxedView/Cells/BaseCell.cs +++ b/src/App/Controls/BoxedView/Cells/BaseCell.cs @@ -5,13 +5,6 @@ namespace Bit.App.Controls.BoxedView { public class BaseCell : Cell { - public new event EventHandler Tapped; - - internal new void OnTapped() - { - Tapped?.Invoke(this, EventArgs.Empty); - } - public static BindableProperty TitleProperty = BindableProperty.Create( nameof(Title), typeof(string), typeof(BaseCell), default(string), defaultBindingMode: BindingMode.OneWay); @@ -83,5 +76,12 @@ namespace Bit.App.Controls.BoxedView } public BoxedSection Section { get; set; } + + public new event EventHandler Tapped; + + protected internal new void OnTapped() + { + Tapped?.Invoke(this, EventArgs.Empty); + } } }