1
0
mirror of https://github.com/bitwarden/mobile.git synced 2024-11-24 11:55:38 +01:00
This commit is contained in:
Kyle Spearrin 2019-04-04 23:00:02 -04:00
parent 61e95e03c8
commit 8006bcf10c
8 changed files with 369 additions and 513 deletions

View File

@ -12,7 +12,7 @@ using Xamarin.Forms;
using Xamarin.Forms.Platform.Android; using Xamarin.Forms.Platform.Android;
using AView = Android.Views.View; using AView = Android.Views.View;
namespace Bit.Droid.Renderers namespace Bit.Droid.Renderers.BoxedView
{ {
[Preserve(AllMembers = true)] [Preserve(AllMembers = true)]
public class BoxedViewRecyclerAdapter : RecyclerView.Adapter, AView.IOnClickListener public class BoxedViewRecyclerAdapter : RecyclerView.Adapter, AView.IOnClickListener
@ -20,8 +20,6 @@ namespace Bit.Droid.Renderers
private const int ViewTypeHeader = 0; private const int ViewTypeHeader = 0;
private const int ViewTypeFooter = 1; private const int ViewTypeFooter = 1;
private float MinRowHeight => _context.ToPixels(44);
private Dictionary<Type, int> _viewTypes; private Dictionary<Type, int> _viewTypes;
private List<CellCache> _cellCaches; private List<CellCache> _cellCaches;
@ -42,28 +40,21 @@ namespace Bit.Droid.Renderers
private AView _preSelectedCell = null; private AView _preSelectedCell = null;
Context _context; Context _context;
BoxedView _boxedView; App.Controls.BoxedView.BoxedView _boxedView;
RecyclerView _recyclerView; RecyclerView _recyclerView;
List<ViewHolder> _viewHolders = new List<ViewHolder>(); List<ViewHolder> _viewHolders = new List<ViewHolder>();
public BoxedViewRecyclerAdapter(Context context, BoxedView boxedView, RecyclerView recyclerView) public BoxedViewRecyclerAdapter(Context context, App.Controls.BoxedView.BoxedView boxedView,
RecyclerView recyclerView)
{ {
_context = context; _context = context;
_boxedView = boxedView; _boxedView = boxedView;
_recyclerView = recyclerView; _recyclerView = recyclerView;
_boxedView.ModelChanged += BoxedView_ModelChanged;
_boxedView.ModelChanged += _boxedView_ModelChanged;
} }
void _boxedView_ModelChanged(object sender, EventArgs e) private float MinRowHeight => _context.ToPixels(44);
{
if(_recyclerView != null)
{
_cellCaches = null;
NotifyDataSetChanged();
}
}
public override int ItemCount => CellCaches.Count; public override int ItemCount => CellCaches.Count;
@ -101,28 +92,24 @@ namespace Bit.Droid.Renderers
{ {
var position = _recyclerView.GetChildAdapterPosition(view); var position = _recyclerView.GetChildAdapterPosition(view);
//TODO: It is desirable that the forms side has Selected property and reflects it. // 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. // But do it at a later as iOS side doesn't have that process.
DeselectRow(); DeselectRow();
var cell = view.FindViewById<LinearLayout>(Resource.Id.ContentCellBody).GetChildAt(0) as BaseCellView; var cell = view.FindViewById<LinearLayout>(Resource.Id.ContentCellBody).GetChildAt(0) as BaseCellView;
if(cell == null || !CellCaches[position].Cell.IsEnabled) if(cell == null || !CellCaches[position].Cell.IsEnabled)
{ {
//if FormsCell IsEnable is false, does nothing. // If FormsCell IsEnable is false, does nothing.
return; return;
} }
_boxedView.Model.RowSelected(CellCaches[position].Cell); _boxedView.Model.RowSelected(CellCaches[position].Cell);
cell.RowSelected(this, position); cell.RowSelected(this, position);
} }
public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position) public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
{ {
var cellInfo = CellCaches[position]; var cellInfo = CellCaches[position];
switch(holder.ItemViewType) switch(holder.ItemViewType)
{ {
case ViewTypeHeader: case ViewTypeHeader:
@ -175,7 +162,7 @@ namespace Bit.Droid.Renderers
{ {
if(disposing) if(disposing)
{ {
_boxedView.ModelChanged -= _boxedView_ModelChanged; _boxedView.ModelChanged -= BoxedView_ModelChanged;
_cellCaches?.Clear(); _cellCaches?.Clear();
_cellCaches = null; _cellCaches = null;
_boxedView = null; _boxedView = null;
@ -190,12 +177,20 @@ namespace Bit.Droid.Renderers
base.Dispose(disposing); base.Dispose(disposing);
} }
private void BoxedView_ModelChanged(object sender, EventArgs e)
{
if(_recyclerView != null)
{
_cellCaches = null;
NotifyDataSetChanged();
}
}
private void BindHeaderView(HeaderViewHolder holder, TextCell formsCell) private void BindHeaderView(HeaderViewHolder holder, TextCell formsCell)
{ {
var view = holder.ItemView; var view = holder.ItemView;
//judging cell height // Judging cell height
int cellHeight = (int)_context.ToPixels(44); int cellHeight = (int)_context.ToPixels(44);
var individualHeight = formsCell.Height; var individualHeight = formsCell.Height;
@ -211,7 +206,6 @@ namespace Bit.Droid.Renderers
view.SetMinimumHeight(cellHeight); view.SetMinimumHeight(cellHeight);
view.LayoutParameters.Height = cellHeight; view.LayoutParameters.Height = cellHeight;
//textview setting
holder.TextView.SetPadding( holder.TextView.SetPadding(
(int)view.Context.ToPixels(_boxedView.HeaderPadding.Left), (int)view.Context.ToPixels(_boxedView.HeaderPadding.Left),
(int)view.Context.ToPixels(_boxedView.HeaderPadding.Top), (int)view.Context.ToPixels(_boxedView.HeaderPadding.Top),
@ -231,7 +225,7 @@ namespace Bit.Droid.Renderers
holder.TextView.SetTextColor(_boxedView.HeaderTextColor.ToAndroid()); holder.TextView.SetTextColor(_boxedView.HeaderTextColor.ToAndroid());
} }
//border setting // Border setting
if(_boxedView.ShowSectionTopBottomBorder) if(_boxedView.ShowSectionTopBottomBorder)
{ {
holder.Border.SetBackgroundColor(_boxedView.SeparatorColor.ToAndroid()); holder.Border.SetBackgroundColor(_boxedView.SeparatorColor.ToAndroid());
@ -241,7 +235,7 @@ namespace Bit.Droid.Renderers
holder.Border.SetBackgroundColor(Android.Graphics.Color.Transparent); holder.Border.SetBackgroundColor(Android.Graphics.Color.Transparent);
} }
//update text // Update text
holder.TextView.Text = formsCell.Text; holder.TextView.Text = formsCell.Text;
} }
@ -249,7 +243,7 @@ namespace Bit.Droid.Renderers
{ {
var view = holder.ItemView; var view = holder.ItemView;
//footer visible setting // Footer visible setting
if(string.IsNullOrEmpty(formsCell.Text)) if(string.IsNullOrEmpty(formsCell.Text))
{ {
//if text is empty, hidden (height 0) //if text is empty, hidden (height 0)
@ -262,7 +256,6 @@ namespace Bit.Droid.Renderers
view.Visibility = ViewStates.Visible; view.Visibility = ViewStates.Visible;
} }
//textview setting
holder.TextView.SetPadding( holder.TextView.SetPadding(
(int)view.Context.ToPixels(_boxedView.FooterPadding.Left), (int)view.Context.ToPixels(_boxedView.FooterPadding.Left),
(int)view.Context.ToPixels(_boxedView.FooterPadding.Top), (int)view.Context.ToPixels(_boxedView.FooterPadding.Top),
@ -276,7 +269,7 @@ namespace Bit.Droid.Renderers
holder.TextView.SetTextColor(_boxedView.FooterTextColor.ToAndroid()); holder.TextView.SetTextColor(_boxedView.FooterTextColor.ToAndroid());
} }
//update text // Update text
holder.TextView.Text = formsCell.Text; holder.TextView.Text = formsCell.Text;
} }
@ -305,31 +298,31 @@ namespace Bit.Droid.Renderers
var minHeight = (int)Math.Max(_context.ToPixels(_boxedView.RowHeight), MinRowHeight); 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); layout.SetMinimumHeight(minHeight);
nativeCell.SetMinimumHeight(minHeight); nativeCell.SetMinimumHeight(minHeight);
if(!_boxedView.HasUnevenRows) 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; layout.LayoutParameters.Height = minHeight;
} }
else if(formsCell.Height > -1) 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.SetMinimumHeight((int)_context.ToPixels(formsCell.Height));
layout.LayoutParameters.Height = (int)_context.ToPixels(formsCell.Height); layout.LayoutParameters.Height = (int)_context.ToPixels(formsCell.Height);
} }
else if(formsCell is ViewCell viewCell) 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); var size = viewCell.View.Measure(_boxedView.Width, double.PositiveInfinity);
viewCell.View.Layout(new Rectangle(0, 0, size.Request.Width, size.Request.Height)); viewCell.View.Layout(new Rectangle(0, 0, size.Request.Width, size.Request.Height));
layout.LayoutParameters.Height = (int)_context.ToPixels(size.Request.Height); layout.LayoutParameters.Height = (int)_context.ToPixels(size.Request.Height);
} }
else else
{ {
layout.LayoutParameters.Height = -2; //wrap_content layout.LayoutParameters.Height = -2; // wrap_content
} }
if(!CellCaches[position].IsLastCell || _boxedView.ShowSectionTopBottomBorder) if(!CellCaches[position].IsLastCell || _boxedView.ShowSectionTopBottomBorder)
@ -446,7 +439,7 @@ namespace Bit.Droid.Renderers
[Preserve(AllMembers = true)] [Preserve(AllMembers = true)]
internal class HeaderViewHolder : ViewHolder internal class HeaderViewHolder : ViewHolder
{ {
public HeaderViewHolder(AView view, BoxedView boxedView) public HeaderViewHolder(AView view, App.Controls.BoxedView.BoxedView boxedView)
: base(view) : base(view)
{ {
TextView = view.FindViewById<TextView>(Resource.Id.HeaderCellText); TextView = view.FindViewById<TextView>(Resource.Id.HeaderCellText);
@ -474,7 +467,7 @@ namespace Bit.Droid.Renderers
{ {
public TextView TextView { get; private set; } public TextView TextView { get; private set; }
public FooterViewHolder(AView view, BoxedView boxedView) public FooterViewHolder(AView view, App.Controls.BoxedView.BoxedView boxedView)
: base(view) : base(view)
{ {
TextView = view.FindViewById<TextView>(Resource.Id.FooterCellText); TextView = view.FindViewById<TextView>(Resource.Id.FooterCellText);

View File

@ -4,17 +4,17 @@ using Android.Support.V7.Widget;
using Android.Support.V7.Widget.Helper; using Android.Support.V7.Widget.Helper;
using Android.Views; using Android.Views;
using Bit.App.Controls.BoxedView; using Bit.App.Controls.BoxedView;
using Bit.Droid.Renderers; using Bit.Droid.Renderers.BoxedView;
using System; using System;
using System.ComponentModel; using System.ComponentModel;
using Xamarin.Forms; using Xamarin.Forms;
using Xamarin.Forms.Platform.Android; using Xamarin.Forms.Platform.Android;
[assembly: ExportRenderer(typeof(BoxedView), typeof(BoxedViewRenderer))] [assembly: ExportRenderer(typeof(BoxedView), typeof(BoxedViewRenderer))]
namespace Bit.Droid.Renderers namespace Bit.Droid.Renderers.BoxedView
{ {
[Preserve(AllMembers = true)] [Preserve(AllMembers = true)]
public class BoxedViewRenderer : ViewRenderer<BoxedView, RecyclerView> public class BoxedViewRenderer : ViewRenderer<App.Controls.BoxedView.BoxedView, RecyclerView>
{ {
private Page _parentPage; private Page _parentPage;
private LinearLayoutManager _layoutManager; private LinearLayoutManager _layoutManager;
@ -28,7 +28,7 @@ namespace Bit.Droid.Renderers
AutoPackage = false; AutoPackage = false;
} }
protected override void OnElementChanged(ElementChangedEventArgs<BoxedView> e) protected override void OnElementChanged(ElementChangedEventArgs<App.Controls.BoxedView.BoxedView> e)
{ {
base.OnElementChanged(e); base.OnElementChanged(e);
if(e.NewElement != null) if(e.NewElement != null)
@ -48,7 +48,8 @@ namespace Bit.Droid.Renderers
_adapter = new BoxedViewRecyclerAdapter(Context, e.NewElement, recyclerView); _adapter = new BoxedViewRecyclerAdapter(Context, e.NewElement, recyclerView);
Control.SetAdapter(_adapter); 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 = new ItemTouchHelper(_simpleCallback);
_itemTouchhelper.AttachToRecyclerView(Control); _itemTouchhelper.AttachToRecyclerView(Control);
@ -100,11 +101,11 @@ namespace Bit.Droid.Renderers
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e) protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{ {
base.OnElementPropertyChanged(sender, e); base.OnElementPropertyChanged(sender, e);
if(e.PropertyName == BoxedView.SeparatorColorProperty.PropertyName) if(e.PropertyName == App.Controls.BoxedView.BoxedView.SeparatorColorProperty.PropertyName)
{ {
_adapter.NotifyDataSetChanged(); _adapter.NotifyDataSetChanged();
} }
else if(e.PropertyName == BoxedView.BackgroundColorProperty.PropertyName) else if(e.PropertyName == App.Controls.BoxedView.BoxedView.BackgroundColorProperty.PropertyName)
{ {
UpdateBackgroundColor(); UpdateBackgroundColor();
} }
@ -112,11 +113,11 @@ namespace Bit.Droid.Renderers
{ {
UpdateRowHeight(); UpdateRowHeight();
} }
else if(e.PropertyName == BoxedView.SelectedColorProperty.PropertyName) else if(e.PropertyName == App.Controls.BoxedView.BoxedView.SelectedColorProperty.PropertyName)
{ {
//_adapter.NotifyDataSetChanged(); //_adapter.NotifyDataSetChanged();
} }
else if(e.PropertyName == BoxedView.ShowSectionTopBottomBorderProperty.PropertyName) else if(e.PropertyName == App.Controls.BoxedView.BoxedView.ShowSectionTopBottomBorderProperty.PropertyName)
{ {
_adapter.NotifyDataSetChanged(); _adapter.NotifyDataSetChanged();
} }
@ -124,11 +125,11 @@ namespace Bit.Droid.Renderers
{ {
_adapter.NotifyDataSetChanged(); _adapter.NotifyDataSetChanged();
} }
else if(e.PropertyName == BoxedView.ScrollToTopProperty.PropertyName) else if(e.PropertyName == App.Controls.BoxedView.BoxedView.ScrollToTopProperty.PropertyName)
{ {
UpdateScrollToTop(); UpdateScrollToTop();
} }
else if(e.PropertyName == BoxedView.ScrollToBottomProperty.PropertyName) else if(e.PropertyName == App.Controls.BoxedView.BoxedView.ScrollToBottomProperty.PropertyName)
{ {
UpdateScrollToBottom(); UpdateScrollToBottom();
} }

View File

@ -1,24 +1,24 @@
using Android.Runtime; using Android.Runtime;
using Android.Support.V7.Widget; using Android.Support.V7.Widget;
using Android.Support.V7.Widget.Helper; using Android.Support.V7.Widget.Helper;
using Bit.App.Controls.BoxedView;
using System; using System;
namespace Bit.Droid.Renderers namespace Bit.Droid.Renderers.BoxedView
{ {
[Preserve(AllMembers = true)] [Preserve(AllMembers = true)]
public class BoxedViewSimpleCallback : ItemTouchHelper.SimpleCallback public class BoxedViewSimpleCallback : ItemTouchHelper.SimpleCallback
{ {
private BoxedView _boxedView; private App.Controls.BoxedView.BoxedView _boxedView;
private int _offset = 0; 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) : base(dragDirs, swipeDirs)
{ {
_boxedView = boxedView; _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)) if(!(viewHolder is ContentViewHolder fromContentHolder))
{ {

View File

@ -8,26 +8,11 @@ using System.Linq.Expressions;
using System.Reflection; using System.Reflection;
using Xamarin.Forms.Platform.Android; using Xamarin.Forms.Platform.Android;
namespace Bit.Droid.Renderers namespace Bit.Droid.Renderers.BoxedView
{ {
[Preserve(AllMembers = true)] [Preserve(AllMembers = true)]
public class BaseCellRenderer<TNativeCell> : CellRenderer where TNativeCell : BaseCellView public class BaseCellRenderer<TNativeCell> : CellRenderer where TNativeCell : BaseCellView
{ {
internal static class InstanceCreator<T1, T2, TInstance>
{
public static Func<T1, T2, TInstance> Create { get; } = CreateInstance();
private static Func<T1, T2, TInstance> 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<Func<T1, T2, TInstance>>(Expression.New(constructor, args), args).Compile();
}
}
protected override View GetCellCore(Xamarin.Forms.Cell item, View convertView, ViewGroup parent, protected override View GetCellCore(Xamarin.Forms.Cell item, View convertView, ViewGroup parent,
Context context) Context context)
{ {
@ -47,7 +32,7 @@ namespace Bit.Droid.Renderers
{ {
var formsCell = nativeCell.Cell as BaseCell; var formsCell = nativeCell.Cell as BaseCell;
formsCell.PropertyChanged += nativeCell.CellPropertyChanged; formsCell.PropertyChanged += nativeCell.CellPropertyChanged;
if(formsCell.Parent is BoxedView parentElement) if(formsCell.Parent is App.Controls.BoxedView.BoxedView parentElement)
{ {
parentElement.PropertyChanged += nativeCell.ParentPropertyChanged; parentElement.PropertyChanged += nativeCell.ParentPropertyChanged;
var section = parentElement.Model.GetSection(BoxedModel.GetPath(formsCell).Item1); var section = parentElement.Model.GetSection(BoxedModel.GetPath(formsCell).Item1);
@ -63,7 +48,7 @@ namespace Bit.Droid.Renderers
{ {
var formsCell = nativeCell.Cell as BaseCell; var formsCell = nativeCell.Cell as BaseCell;
formsCell.PropertyChanged -= nativeCell.CellPropertyChanged; formsCell.PropertyChanged -= nativeCell.CellPropertyChanged;
if(formsCell.Parent is BoxedView parentElement) if(formsCell.Parent is App.Controls.BoxedView.BoxedView parentElement)
{ {
parentElement.PropertyChanged -= nativeCell.ParentPropertyChanged; parentElement.PropertyChanged -= nativeCell.ParentPropertyChanged;
if(formsCell.Section != null) if(formsCell.Section != null)
@ -72,5 +57,20 @@ namespace Bit.Droid.Renderers
} }
} }
} }
internal static class InstanceCreator<T1, T2, TInstance>
{
public static Func<T1, T2, TInstance> Create { get; } = CreateInstance();
private static Func<T1, T2, TInstance> 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<Func<T1, T2, TInstance>>(Expression.New(constructor, args), args).Compile();
}
}
} }
} }

View File

@ -12,7 +12,7 @@ using Xamarin.Forms;
using Xamarin.Forms.Platform.Android; using Xamarin.Forms.Platform.Android;
using ARelativeLayout = Android.Widget.RelativeLayout; using ARelativeLayout = Android.Widget.RelativeLayout;
namespace Bit.Droid.Renderers namespace Bit.Droid.Renderers.BoxedView
{ {
[Preserve(AllMembers = true)] [Preserve(AllMembers = true)]
public class BaseCellView : ARelativeLayout, INativeElementView public class BaseCellView : ARelativeLayout, INativeElementView
@ -37,7 +37,7 @@ namespace Bit.Droid.Renderers
public Cell Cell { get; set; } public Cell Cell { get; set; }
public Element Element => Cell; public Element Element => Cell;
protected BaseCell CellBase => Cell as BaseCell; 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 TitleLabel { get; set; }
public TextView DescriptionLabel { get; set; } public TextView DescriptionLabel { get; set; }
public LinearLayout ContentStack { get; set; } public LinearLayout ContentStack { get; set; }
@ -122,27 +122,27 @@ namespace Bit.Droid.Renderers
return; return;
} }
if(e.PropertyName == BoxedView.CellTitleColorProperty.PropertyName) if(e.PropertyName == App.Controls.BoxedView.BoxedView.CellTitleColorProperty.PropertyName)
{ {
UpdateTitleColor(); UpdateTitleColor();
} }
else if(e.PropertyName == BoxedView.CellTitleFontSizeProperty.PropertyName) else if(e.PropertyName == App.Controls.BoxedView.BoxedView.CellTitleFontSizeProperty.PropertyName)
{ {
UpdateWithForceLayout(UpdateTitleFontSize); UpdateWithForceLayout(UpdateTitleFontSize);
} }
else if(e.PropertyName == BoxedView.CellDescriptionColorProperty.PropertyName) else if(e.PropertyName == App.Controls.BoxedView.BoxedView.CellDescriptionColorProperty.PropertyName)
{ {
UpdateDescriptionColor(); UpdateDescriptionColor();
} }
else if(e.PropertyName == BoxedView.CellDescriptionFontSizeProperty.PropertyName) else if(e.PropertyName == App.Controls.BoxedView.BoxedView.CellDescriptionFontSizeProperty.PropertyName)
{ {
UpdateWithForceLayout(UpdateDescriptionFontSize); UpdateWithForceLayout(UpdateDescriptionFontSize);
} }
else if(e.PropertyName == BoxedView.CellBackgroundColorProperty.PropertyName) else if(e.PropertyName == App.Controls.BoxedView.BoxedView.CellBackgroundColorProperty.PropertyName)
{ {
UpdateBackgroundColor(); UpdateBackgroundColor();
} }
else if(e.PropertyName == BoxedView.SelectedColorProperty.PropertyName) else if(e.PropertyName == App.Controls.BoxedView.BoxedView.SelectedColorProperty.PropertyName)
{ {
UpdateWithForceLayout(UpdateSelectedColor); UpdateWithForceLayout(UpdateSelectedColor);
} }

View File

@ -4,13 +4,13 @@ using Android.Text;
using Android.Views; using Android.Views;
using Android.Widget; using Android.Widget;
using Bit.App.Controls.BoxedView; using Bit.App.Controls.BoxedView;
using Bit.Droid.Renderers; using Bit.Droid.Renderers.BoxedView;
using System.ComponentModel; using System.ComponentModel;
using Xamarin.Forms; using Xamarin.Forms;
using Xamarin.Forms.Platform.Android; using Xamarin.Forms.Platform.Android;
[assembly: ExportRenderer(typeof(LabelCell), typeof(LabelCellRenderer))] [assembly: ExportRenderer(typeof(LabelCell), typeof(LabelCellRenderer))]
namespace Bit.Droid.Renderers namespace Bit.Droid.Renderers.BoxedView
{ {
[Preserve(AllMembers = true)] [Preserve(AllMembers = true)]
public class LabelCellRenderer : BaseCellRenderer<LabelCellView> public class LabelCellRenderer : BaseCellRenderer<LabelCellView>
@ -59,11 +59,11 @@ namespace Bit.Droid.Renderers
public override void ParentPropertyChanged(object sender, PropertyChangedEventArgs e) public override void ParentPropertyChanged(object sender, PropertyChangedEventArgs e)
{ {
base.ParentPropertyChanged(sender, e); base.ParentPropertyChanged(sender, e);
if(e.PropertyName == BoxedView.CellValueTextColorProperty.PropertyName) if(e.PropertyName == App.Controls.BoxedView.BoxedView.CellValueTextColorProperty.PropertyName)
{ {
UpdateValueTextColor(); UpdateValueTextColor();
} }
else if(e.PropertyName == BoxedView.CellValueTextFontSizeProperty.PropertyName) else if(e.PropertyName == App.Controls.BoxedView.BoxedView.CellValueTextFontSizeProperty.PropertyName)
{ {
UpdateValueTextFontSize(); UpdateValueTextFontSize();
} }

View File

@ -9,9 +9,117 @@ namespace Bit.App.Controls.BoxedView
[ContentProperty("Root")] [ContentProperty("Root")]
public class BoxedView : TableView 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() 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() protected override void OnBindingContextChanged()
{ {
base.OnBindingContextChanged(); base.OnBindingContextChanged();
@ -56,9 +336,10 @@ namespace Bit.App.Controls.BoxedView
private void RootOnPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) 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.FooterTextProperty.PropertyName ||
e.PropertyName == BoxedSection.IsVisibleProperty.PropertyName) e.PropertyName == BoxedSection.IsVisibleProperty.PropertyName;
if(changed)
{ {
OnModelChanged(); OnModelChanged();
} }
@ -108,424 +389,6 @@ namespace Bit.App.Controls.BoxedView
ModelChanged?.Invoke(this, EventArgs.Empty); 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) private static void ItemsChanged(BindableObject bindable, object oldValue, object newValue)
{ {
var boxedView = bindable as BoxedView; var boxedView = bindable as BoxedView;
@ -542,7 +405,6 @@ namespace Bit.App.Controls.BoxedView
{ {
newObservableCollection.CollectionChanged += boxedView.OnItemsSourceCollectionChanged; newObservableCollection.CollectionChanged += boxedView.OnItemsSourceCollectionChanged;
} }
boxedView.Root.Clear(); boxedView.Root.Clear();
if(newValue is IList newValueAsEnumerable) if(newValue is IList newValueAsEnumerable)

View File

@ -5,13 +5,6 @@ namespace Bit.App.Controls.BoxedView
{ {
public class BaseCell : Cell public class BaseCell : Cell
{ {
public new event EventHandler Tapped;
internal new void OnTapped()
{
Tapped?.Invoke(this, EventArgs.Empty);
}
public static BindableProperty TitleProperty = BindableProperty.Create( public static BindableProperty TitleProperty = BindableProperty.Create(
nameof(Title), typeof(string), typeof(BaseCell), default(string), defaultBindingMode: BindingMode.OneWay); 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 BoxedSection Section { get; set; }
public new event EventHandler Tapped;
protected internal new void OnTapped()
{
Tapped?.Invoke(this, EventArgs.Empty);
}
} }
} }