1
0
mirror of https://github.com/bitwarden/mobile synced 2025-12-29 14:43:50 +00:00

BoxedView with LabelCell

This commit is contained in:
Kyle Spearrin
2019-04-04 22:28:03 -04:00
parent 2b2342bcad
commit 61e95e03c8
21 changed files with 2945 additions and 285 deletions

View File

@@ -0,0 +1,85 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Xamarin.Forms;
using Xamarin.Forms.Internals;
namespace Bit.App.Controls.BoxedView
{
public class BoxedModel : TableModel
{
private static readonly BindableProperty PathProperty = BindableProperty.Create(
"Path", typeof(Tuple<int, int>), typeof(Cell), null);
private BoxedRoot _root;
private IEnumerable<BoxedSection> _visibleSections;
public BoxedModel(BoxedRoot root)
{
_root = root;
_visibleSections = _root.Where(x => x.IsVisible);
}
public override Cell GetCell(int section, int row)
{
var cell = (Cell)GetItem(section, row);
SetPath(cell, new Tuple<int, int>(section, row));
return cell;
}
public override object GetItem(int section, int row)
{
return _visibleSections.ElementAt(section)[row];
}
public override int GetRowCount(int section)
{
return _visibleSections.ElementAt(section).Count;
}
public override int GetSectionCount()
{
return _visibleSections.Count();
}
public virtual BoxedSection GetSection(int section)
{
return _visibleSections.ElementAtOrDefault(section);
}
public override string GetSectionTitle(int section)
{
return _visibleSections.ElementAt(section).Title;
}
public virtual string GetFooterText(int section)
{
return _visibleSections.ElementAt(section).FooterText;
}
protected override void OnRowSelected(object item)
{
base.OnRowSelected(item);
(item as BaseCell)?.OnTapped();
}
public virtual double GetHeaderHeight(int section)
{
return _visibleSections.ElementAt(section).HeaderHeight;
}
public static Tuple<int, int> GetPath(Cell item)
{
if(item == null)
{
throw new ArgumentNullException(nameof(item));
}
return item.GetValue(PathProperty) as Tuple<int, int>;
}
private static void SetPath(Cell item, Tuple<int, int> index)
{
item?.SetValue(PathProperty, index);
}
}
}

View File

@@ -0,0 +1,61 @@
using System;
using System.Collections.Specialized;
using System.ComponentModel;
using Xamarin.Forms;
namespace Bit.App.Controls.BoxedView
{
public class BoxedRoot : TableSectionBase<BoxedSection>
{
public BoxedRoot()
{
SetupEvents();
}
public event EventHandler<EventArgs> SectionCollectionChanged;
private void ChildCollectionChanged(object sender, NotifyCollectionChangedEventArgs args)
{
SectionCollectionChanged?.Invoke(this, EventArgs.Empty);
}
private void ChildPropertyChanged(object sender, PropertyChangedEventArgs e)
{
if(e.PropertyName == TitleProperty.PropertyName)
{
OnPropertyChanged(TitleProperty.PropertyName);
}
else if(e.PropertyName == BoxedSection.FooterTextProperty.PropertyName)
{
OnPropertyChanged(BoxedSection.FooterTextProperty.PropertyName);
}
else if(e.PropertyName == BoxedSection.IsVisibleProperty.PropertyName)
{
OnPropertyChanged(BoxedSection.IsVisibleProperty.PropertyName);
}
}
private void SetupEvents()
{
CollectionChanged += (sender, args) =>
{
if(args.NewItems != null)
{
foreach(BoxedSection section in args.NewItems)
{
section.CollectionChanged += ChildCollectionChanged;
section.PropertyChanged += ChildPropertyChanged;
}
}
if(args.OldItems != null)
{
foreach(BoxedSection section in args.OldItems)
{
section.CollectionChanged -= ChildCollectionChanged;
section.PropertyChanged -= ChildPropertyChanged;
}
}
};
}
}
}

View File

@@ -0,0 +1,147 @@
using System.Collections;
using System.Collections.Specialized;
using Xamarin.Forms;
namespace Bit.App.Controls.BoxedView
{
public class BoxedSection : TableSectionBase<Cell>
{
public static BindableProperty IsVisibleProperty = BindableProperty.Create(
nameof(IsVisible), typeof(bool), typeof(BoxedSection), true, defaultBindingMode: BindingMode.OneWay);
public static BindableProperty FooterTextProperty = BindableProperty.Create(
nameof(FooterText), typeof(string), typeof(BoxedSection), default(string),
defaultBindingMode: BindingMode.OneWay);
public static BindableProperty ItemTemplateProperty = BindableProperty.Create(
nameof(ItemTemplate), typeof(DataTemplate), typeof(BoxedSection), default(DataTemplate),
defaultBindingMode: BindingMode.OneWay);
public static BindableProperty ItemsSourceProperty = BindableProperty.Create(
nameof(ItemsSource), typeof(IList), typeof(BoxedSection), default(IList),
defaultBindingMode: BindingMode.OneWay, propertyChanged: ItemsChanged);
public static BindableProperty HeaderHeightProperty = BindableProperty.Create(
nameof(HeaderHeight), typeof(double), typeof(BoxedSection), -1d, defaultBindingMode: BindingMode.OneWay);
public static BindableProperty UseDragSortProperty = BindableProperty.Create(
nameof(UseDragSort), typeof(bool), typeof(BoxedSection), false, defaultBindingMode: BindingMode.OneWay);
public BoxedSection()
{ }
public BoxedSection(string title)
: base(title)
{ }
public bool IsVisible
{
get => (bool)GetValue(IsVisibleProperty);
set => SetValue(IsVisibleProperty, value);
}
public string FooterText
{
get => (string)GetValue(FooterTextProperty);
set => SetValue(FooterTextProperty, value);
}
public DataTemplate ItemTemplate
{
get => (DataTemplate)GetValue(ItemTemplateProperty);
set => SetValue(ItemTemplateProperty, value);
}
public IList ItemsSource
{
get => (IList)GetValue(ItemsSourceProperty);
set => SetValue(ItemsSourceProperty, value);
}
public double HeaderHeight
{
get => (double)GetValue(HeaderHeightProperty);
set => SetValue(HeaderHeightProperty, value);
}
public bool UseDragSort
{
get => (bool)GetValue(UseDragSortProperty);
set => SetValue(UseDragSortProperty, value);
}
private static void ItemsChanged(BindableObject bindable, object oldValue, object newValue)
{
var section = bindable as BoxedSection;
if(section.ItemTemplate == null)
{
return;
}
if(oldValue is INotifyCollectionChanged oldObservableCollection)
{
oldObservableCollection.CollectionChanged -= section.OnItemsSourceCollectionChanged;
}
if(newValue is INotifyCollectionChanged newObservableCollection)
{
newObservableCollection.CollectionChanged += section.OnItemsSourceCollectionChanged;
}
section.Clear();
if(newValue is IList newValueAsEnumerable)
{
foreach(var item in newValueAsEnumerable)
{
var view = CreateChildViewFor(section.ItemTemplate, item, section);
section.Add(view);
}
}
}
private void OnItemsSourceCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
if(e.Action == NotifyCollectionChangedAction.Replace)
{
RemoveAt(e.OldStartingIndex);
var item = e.NewItems[e.NewStartingIndex];
var view = CreateChildViewFor(ItemTemplate, item, this);
Insert(e.NewStartingIndex, view);
}
else if(e.Action == NotifyCollectionChangedAction.Add)
{
if(e.NewItems != null)
{
for(var i = 0; i < e.NewItems.Count; ++i)
{
var item = e.NewItems[i];
var view = CreateChildViewFor(ItemTemplate, item, this);
Insert(i + e.NewStartingIndex, view);
}
}
}
else if(e.Action == NotifyCollectionChangedAction.Remove)
{
if(e.OldItems != null)
{
RemoveAt(e.OldStartingIndex);
}
}
else if(e.Action == NotifyCollectionChangedAction.Reset)
{
Clear();
}
}
private static Cell CreateChildViewFor(DataTemplate template, object item, BindableObject container)
{
if(template is DataTemplateSelector selector)
{
template = selector.SelectTemplate(item, container);
}
// Binding context
template.SetValue(BindingContextProperty, item);
return template.CreateContent() as Cell;
}
}
}

View File

@@ -0,0 +1,602 @@
using System;
using System.Collections;
using System.Collections.Specialized;
using System.Linq;
using Xamarin.Forms;
namespace Bit.App.Controls.BoxedView
{
[ContentProperty("Root")]
public class BoxedView : TableView
{
private BoxedRoot _root;
public new event EventHandler ModelChanged;
public BoxedView()
{
VerticalOptions = HorizontalOptions = LayoutOptions.FillAndExpand;
Root = new BoxedRoot();
Model = new BoxedModel(Root);
}
public new BoxedModel Model { get; set; }
public new BoxedRoot Root
{
get => _root;
set
{
if(_root != null)
{
_root.PropertyChanged -= RootOnPropertyChanged;
_root.CollectionChanged -= OnCollectionChanged;
_root.SectionCollectionChanged -= OnSectionCollectionChanged;
}
_root = value;
// Transfer binding context to the children (maybe...)
SetInheritedBindingContext(_root, BindingContext);
_root.PropertyChanged += RootOnPropertyChanged;
_root.CollectionChanged += OnCollectionChanged;
_root.SectionCollectionChanged += OnSectionCollectionChanged;
}
}
protected override void OnBindingContextChanged()
{
base.OnBindingContextChanged();
if(Root != null)
{
SetInheritedBindingContext(Root, BindingContext);
}
}
private void RootOnPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
if(e.PropertyName == TableSectionBase.TitleProperty.PropertyName ||
e.PropertyName == BoxedSection.FooterTextProperty.PropertyName ||
e.PropertyName == BoxedSection.IsVisibleProperty.PropertyName)
{
OnModelChanged();
}
}
protected override void OnPropertyChanged(string propertyName = null)
{
base.OnPropertyChanged(propertyName);
var changed = propertyName == HasUnevenRowsProperty.PropertyName ||
propertyName == HeaderHeightProperty.PropertyName ||
propertyName == HeaderFontSizeProperty.PropertyName ||
propertyName == HeaderTextColorProperty.PropertyName ||
propertyName == HeaderBackgroundColorProperty.PropertyName ||
propertyName == HeaderTextVerticalAlignProperty.PropertyName ||
propertyName == HeaderPaddingProperty.PropertyName ||
propertyName == FooterFontSizeProperty.PropertyName ||
propertyName == FooterTextColorProperty.PropertyName ||
propertyName == FooterBackgroundColorProperty.PropertyName ||
propertyName == FooterPaddingProperty.PropertyName;
if(changed)
{
OnModelChanged();
}
}
public void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
OnModelChanged();
}
public void OnSectionCollectionChanged(object sender, EventArgs childCollectionChangedEventArgs)
{
OnModelChanged();
}
protected new void OnModelChanged()
{
var cells = Root?.SelectMany(r => r);
if(cells == null)
{
return;
}
foreach(var cell in cells)
{
cell.Parent = this;
}
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;
if(boxedView.ItemTemplate == null)
{
return;
}
if(oldValue is INotifyCollectionChanged oldObservableCollection)
{
oldObservableCollection.CollectionChanged -= boxedView.OnItemsSourceCollectionChanged;
}
if(newValue is INotifyCollectionChanged newObservableCollection)
{
newObservableCollection.CollectionChanged += boxedView.OnItemsSourceCollectionChanged;
}
boxedView.Root.Clear();
if(newValue is IList newValueAsEnumerable)
{
foreach(var item in newValueAsEnumerable)
{
var view = CreateChildViewFor(boxedView.ItemTemplate, item, boxedView);
boxedView.Root.Add(view);
}
}
}
private void OnItemsSourceCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
if(e.Action == NotifyCollectionChangedAction.Replace)
{
Root.RemoveAt(e.OldStartingIndex);
var item = e.NewItems[e.NewStartingIndex];
var view = CreateChildViewFor(ItemTemplate, item, this);
Root.Insert(e.NewStartingIndex, view);
}
else if(e.Action == NotifyCollectionChangedAction.Add)
{
if(e.NewItems != null)
{
for(var i = 0; i < e.NewItems.Count; ++i)
{
var item = e.NewItems[i];
var view = CreateChildViewFor(ItemTemplate, item, this);
Root.Insert(i + e.NewStartingIndex, view);
}
}
}
else if(e.Action == NotifyCollectionChangedAction.Remove)
{
if(e.OldItems != null)
{
Root.RemoveAt(e.OldStartingIndex);
}
}
else if(e.Action == NotifyCollectionChangedAction.Reset)
{
Root.Clear();
}
}
private static BoxedSection CreateChildViewFor(DataTemplate template, object item, BindableObject container)
{
if(template is DataTemplateSelector selector)
{
template = selector.SelectTemplate(item, container);
}
template.SetValue(BindingContextProperty, item);
return template.CreateContent() as BoxedSection;
}
}
}

View File

@@ -0,0 +1,87 @@
using System;
using Xamarin.Forms;
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);
public static BindableProperty TitleColorProperty = BindableProperty.Create(
nameof(TitleColor), typeof(Color), typeof(BaseCell), default(Color),
defaultBindingMode: BindingMode.OneWay);
public static BindableProperty TitleFontSizeProperty = BindableProperty.Create(
nameof(TitleFontSize), typeof(double), typeof(BaseCell), -1.0, defaultBindingMode: BindingMode.OneWay);
public static BindableProperty DescriptionProperty = BindableProperty.Create(
nameof(Description), typeof(string), typeof(BaseCell), default(string),
defaultBindingMode: BindingMode.OneWay);
public static BindableProperty DescriptionColorProperty = BindableProperty.Create(
nameof(DescriptionColor), typeof(Color), typeof(BaseCell), default(Color),
defaultBindingMode: BindingMode.OneWay);
public static BindableProperty DescriptionFontSizeProperty = BindableProperty.Create(
nameof(DescriptionFontSize), typeof(double), typeof(BaseCell), -1.0d,
defaultBindingMode: BindingMode.OneWay);
public static BindableProperty BackgroundColorProperty = BindableProperty.Create(
nameof(BackgroundColor), typeof(Color), typeof(BaseCell), default(Color),
defaultBindingMode: BindingMode.OneWay);
public string Title
{
get => (string)GetValue(TitleProperty);
set => SetValue(TitleProperty, value);
}
public Color TitleColor
{
get => (Color)GetValue(TitleColorProperty);
set => SetValue(TitleColorProperty, value);
}
[TypeConverter(typeof(FontSizeConverter))]
public double TitleFontSize
{
get => (double)GetValue(TitleFontSizeProperty);
set => SetValue(TitleFontSizeProperty, value);
}
public string Description
{
get => (string)GetValue(DescriptionProperty);
set => SetValue(DescriptionProperty, value);
}
public Color DescriptionColor
{
get => (Color)GetValue(DescriptionColorProperty);
set => SetValue(DescriptionColorProperty, value);
}
[TypeConverter(typeof(FontSizeConverter))]
public double DescriptionFontSize
{
get => (double)GetValue(DescriptionFontSizeProperty);
set => SetValue(DescriptionFontSizeProperty, value);
}
public Color BackgroundColor
{
get => (Color)GetValue(BackgroundColorProperty);
set => SetValue(BackgroundColorProperty, value);
}
public BoxedSection Section { get; set; }
}
}

View File

@@ -0,0 +1,38 @@
using Xamarin.Forms;
namespace Bit.App.Controls.BoxedView
{
public class LabelCell : BaseCell
{
public static BindableProperty ValueTextProperty = BindableProperty.Create(
nameof(ValueText), typeof(string), typeof(LabelCell), default(string),
defaultBindingMode: BindingMode.OneWay);
public static BindableProperty ValueTextColorProperty = BindableProperty.Create(
nameof(ValueTextColor), typeof(Color), typeof(LabelCell), default(Color),
defaultBindingMode: BindingMode.OneWay);
public static BindableProperty ValueTextFontSizeProperty = BindableProperty.Create(
nameof(ValueTextFontSize), typeof(double), typeof(LabelCell), -1.0d,
defaultBindingMode: BindingMode.OneWay);
public string ValueText
{
get => (string)GetValue(ValueTextProperty);
set => SetValue(ValueTextProperty, value);
}
public Color ValueTextColor
{
get => (Color)GetValue(ValueTextColorProperty);
set => SetValue(ValueTextColorProperty, value);
}
[TypeConverter(typeof(FontSizeConverter))]
public double ValueTextFontSize
{
get => (double)GetValue(ValueTextFontSizeProperty);
set => SetValue(ValueTextFontSizeProperty, value);
}
}
}