How to set Datepicker default index is string value - xamarin

I want to show datepicker default index value is string but I am not able to do that. Please suggest any idea. Thanks in advance.
I want to show picker like this:

You can use a UITextField and add date picker as a Input vie. And set PlaceHolder as "Date" or any string you want.
Sample Code
UITextField TextInput = new UITextField();
TextInput.Frame = new CGRect(40, 280, View.Frame.Width - 80, 40);
TextInput.Placeholder = "Date";
var picker = new UIDatePicker();
TextInput.InputView = picker;

Here is an example how to do it in ViewCell. You can use similar idea with View
public class TimePickerInCellPage : ContentPage
{
private ListView _listView;
public TimePickerInCellPage()
{
_listView = new ListView
{
RowHeight = 80,
SeparatorColor = Color.Blue,
SeparatorVisibility = SeparatorVisibility.Default
};
_listView.ItemsSource = new List<TaskTime>() {
new TaskTime { Id=1, StartTime=TimeSpan.FromHours(3) } ,
new TaskTime { Id=1, StartTime=TimeSpan.FromHours(5) } ,
new TaskTime { Id=1, StartTime=TimeSpan.FromHours(7) } ,
};
_listView.ItemTemplate = new DataTemplate(typeof(MyCell));
Content = new StackLayout
{
VerticalOptions = LayoutOptions.FillAndExpand,
Children = { _listView }
};
}
}
public class TaskTime
{
public int Id { get; set; }
public string Task { get; set; }
public TimeSpan StartTime { get; set; }
}
class MyCell : ViewCell
{
private readonly DatePicker _myTimePicker;
//private readonly TimePicker _myTimePicker;
public MyCell()
{
//_myTimePicker = new TimePicker()
_myTimePicker = new DatePicker()
{
HorizontalOptions = LayoutOptions.EndAndExpand
};
//_myTimePicker.Format = "HH:mm:ss";
_myTimePicker.Format = "dd:MM:yy HH:mm:ss";
_myTimePicker.SetBinding(TimePicker.TimeProperty, "StartTime");
_myTimePicker.PropertyChanged += MyTimePicker_PropertyChanged;
//_myTimePicker.Focused += _myTimePicker_Focused;
var viewLayout = new StackLayout()
{
HorizontalOptions = LayoutOptions.StartAndExpand,
Orientation = StackOrientation.Horizontal,
Padding = new Thickness(20),
Children = { _myTimePicker }
};
View = viewLayout;
}
bool firstTimeSet; //set when initial binding happens
//private void _myTimePicker_Focused(object sender, FocusEventArgs e)
//{
// firstTimeSet=true;
//}
private void MyTimePicker_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
//if (e.PropertyName == TimePicker.TimeProperty.PropertyName)
if (e.PropertyName == DatePicker.DateProperty.PropertyName)
{
if (!firstTimeSet)
firstTimeSet = true;
else
{
int x = 0;
string s = _myTimePicker.Date.ToString("dd/MM/yy HH:mm:ss");
}
}
}
}

Related

Adding left and right full swipe gesture on listview using xamarin forms

Currently i have a listview which stores the medications of my users, i want to implement a swipe gesture so that the user can simply swipe left or right to tell if the medication has been taken or not taken.
Is there a way to add a left and right full swipe gesture in a listview just like the way that apple has implemented in their mail.
Note:it cannot achieved moved item follow with fingertip, but could achieved left and right gestures
First, you should build swipe compoment using gesture
SwipeGestureGrid.cs
public class SwipeGestureGrid : Grid
{
#region Private Member
private double _gestureX { get; set; }
private double _gestureY { get; set; }
private bool IsSwipe { get; set; }
#endregion
#region Public Member
#region Events
#region Tapped
public event EventHandler Tapped;
protected void OnTapped(EventArgs e)
{
if (Tapped != null)
Tapped(this, e);
}
#endregion
#region SwipeUP
public event EventHandler SwipeUP;
protected void OnSwipeUP(EventArgs e)
{
if (SwipeUP != null)
SwipeUP(this, e);
}
#endregion
#region SwipeDown
public event EventHandler SwipeDown;
protected void OnSwipeDown(EventArgs e)
{
if (SwipeDown != null)
SwipeDown(this, e);
}
#endregion
#region SwipeRight
public event EventHandler SwipeRight;
protected void OnSwipeRight(EventArgs e)
{
if (SwipeRight != null)
SwipeRight(this, e);
}
#endregion
#region SwipeLeft
public event EventHandler SwipeLeft;
protected void OnSwipeLeft(EventArgs e)
{
if (SwipeLeft != null)
SwipeLeft(this, e);
}
#endregion
#endregion
public double Height
{
get
{
return HeightRequest;
}
set
{
HeightRequest = value;
}
}
public double Width
{
get
{
return WidthRequest;
}
set
{
WidthRequest = value;
}
}
#endregion
public SwipeGestureGrid()
{
PanGestureRecognizer panGesture = new PanGestureRecognizer();
panGesture.PanUpdated += PanGesture_PanUpdated;
TapGestureRecognizer tapGesture = new TapGestureRecognizer();
tapGesture.Tapped += TapGesture_Tapped;
GestureRecognizers.Add(panGesture);
GestureRecognizers.Add(tapGesture);
}
private void TapGesture_Tapped(object sender, EventArgs e)
{
try
{
if (!IsSwipe)
OnTapped(null);
IsSwipe = false;
}
catch (Exception ex)
{
}
}
private void PanGesture_PanUpdated(object sender, PanUpdatedEventArgs e)
{
try
{
switch (e.StatusType)
{
case GestureStatus.Running:
{
_gestureX = e.TotalX;
_gestureY = e.TotalY;
}
break;
case GestureStatus.Completed:
{
IsSwipe = true;
//Debug.WriteLine("{0} {1}", _gestureX, _gestureY);
if (Math.Abs(_gestureX) > Math.Abs(_gestureY))
{
if (_gestureX > 0)
{
OnSwipeRight(null);
}
else
{
OnSwipeLeft(null);
}
}
else
{
if (_gestureY > 0)
{
OnSwipeDown(null);
}
else
{
OnSwipeUP(null);
}
}
}
break;
}
}
catch (Exception ex)
{
}
}
}
Next using datatemplate in listview andattach event for GesturecompomentPage.cs
ListView lsvData = new ListView()
{
VerticalOptions = LayoutOptions.Fill,
HorizontalOptions = LayoutOptions.Fill,
BackgroundColor = Color.White,
HasUnevenRows = true,
};
List<string> lstData = new List<string>();
public Pages()
{
#region DataTemplate
DataTemplate ListDataTemplate = new DataTemplate(() =>
{
#region DataArea of Template
SwipeGestureGrid gridData = new SwipeGestureGrid()
{
HorizontalOptions = LayoutOptions.FillAndExpand,
VerticalOptions = LayoutOptions.FillAndExpand,
HeightRequest = 60,
RowDefinitions =
{
new RowDefinition { },
},
ColumnDefinitions =
{
new ColumnDefinition { },
}
};
#endregion
#region Base of Template
Grid gridBase = new Grid()
{
HorizontalOptions = LayoutOptions.FillAndExpand,
VerticalOptions = LayoutOptions.FillAndExpand,
HeightRequest = 60,
RowDefinitions =
{
new RowDefinition { },
},
ColumnDefinitions =
{
new ColumnDefinition { },
//Put Cells Data here
new ColumnDefinition { Width = new GridLength(0,
GridUnitType.Absolute)}, //Button for Cells here
},
};
#endregion
Label lblText = new Label
{
HorizontalOptions = LayoutOptions.FillAndExpand,
VerticalOptions = LayoutOptions.FillAndExpand,
FontAttributes = FontAttributes.Bold,
VerticalTextAlignment = TextAlignment.End,
TextColor = Color.Black,
BackgroundColor = Color.Silver,
LineBreakMode = LineBreakMode.TailTruncation,
FontSize = 18,
};
lblText.SetBinding(Label.TextProperty, ".");
ImageButton btnCellDelete = new ImageButton() { Source = "Delete" };
gridData.Children.Add(lblText, 0, 0);
gridBase.Children.Add(gridData, 0, 0);
gridBase.Children.Add(btnCellDelete, 1, 0);
gridData.SwipeLeft += GridTemplate_SwipeLeft;
gridData.SwipeRight += GridTemplate_SwipeRight; ;
gridData.Tapped += GridTemplate_Tapped; ;
btnCellDelete.Clicked += BtnCellDelete_Clicked; ;
return new ViewCell
{
View = gridBase,
Height = 60,
};
});
#endregion
for (int i = 1; i <= 100; i++)
{
lstData.Add(i.ToString());
}
lsvData.ItemTemplate = ListDataTemplate;
lsvData.ItemsSource = lstData;
Content = lsvData;
}
Add the event.SwipeLeft to show DeleteButton
private void GridTemplate_SwipeLeft(object sender, EventArgs e)
{
try
{
if (sender is SwipeGestureGrid)
{
var templateGrid = ((SwipeGestureGrid)sender).Parent;
if (templateGrid != null && templateGrid is Grid)
{
var CellTemplateGrid = (Grid)templateGrid;
CellTemplateGrid.ColumnDefinitions[1].Width = new GridLength(60, GridUnitType.Absolute);
}
}
}
catch (Exception ex)
{
}
}
swiperight to hide delete button
private void GridTemplate_SwipeRight(object sender, EventArgs e)
{
try
{
if (sender is SwipeGestureGrid)
{
var templateGrid = ((SwipeGestureGrid)sender).Parent;
if (templateGrid != null && templateGrid is Grid)
{
var CellTemplateGrid = (Grid)templateGrid;
CellTemplateGrid.ColumnDefinitions[1].Width = new GridLength(0, GridUnitType.Absolute);
}
}
}
catch (Exception ex)
{
}
}
Delete button click event
private void BtnCellDelete_Clicked(object sender, EventArgs e)
{
try
{
if (sender is ImageButton)
{
var templateGrid = ((ImageButton)sender);
//templateGrid.Parent = gridBase
//templateGrid.Parent.Parent = cell
if (templateGrid.Parent != null && templateGrid.Parent.Parent != null && templateGrid.Parent.Parent.BindingContext != null && templateGrid.Parent.Parent.BindingContext is string)
{
var deletedate = templateGrid.Parent.Parent.BindingContext as string;
lstData.RemoveAll(f => f == deletedate);
lsvData.ItemsSource = null;
lsvData.ItemsSource = lstData;
}
}
}
catch (Exception ex)
{
}
}
There is all code.
https://github.com/act70255/ListViewSwipeGesture
I will create a listview with a custom cells
https://learn.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/listview/customizing-cell-appearance
and i add swipe left and right gestures on a grid inside to a ViewCell
https://learn.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/gestures/swipe
on left swipe i expand with animation something like a grid column where on start the width is 0 and after swap animated to some width. Same with right swipe.
Check for the animation the OnExpandExchange() method from here
https://github.com/xamarinium/FlippingAndResizableUI/blob/master/FlippingAndResizableView/BitcoinView.xaml.cs

xamarin binding variable to label using timer event

I want to binding a variable to a label which as a children in a grid.
the variable changed with a timer event.pls check my code help me found out where i am wrong.I can see the label init value is 0,but it won't update when the variable do.
public class DevicePage : ContentPage
{
IDevice device;
Label testLb = new Label();
System.Timers.Timer testtimer;
Grid gridView;
byte testt { get; set; } = 0;
GetSendData communicate;
private byte _maintext;
public byte MainText
{
get
{
return _maintext;
}
set
{
_maintext = value;
OnPropertyChanged();
}
}
public DevicePage(IDevice currDevice)
{
device = currDevice;
this.Title = "Status";
testtimer = new System.Timers.Timer();
testtimer.Interval = 1000;
testtimer.Elapsed += OnTimedEvent;
testtimer.Enabled = true;
gridView = new Grid();
testLb.Text = testt.ToString();
testLb.SetBinding(Label.TextProperty, ".");
testLb.BindingContext = MainText;
gridView.Children.Add(testLb, 0, 0);
this.Content = gridView;
}
private void OnTimedEvent(object sender, System.Timers.ElapsedEventArgs e)
{
MainText += 1;
}
after I implement INotifyPropertyChanged,testLb won't update either.But I change testLb.SetBinding(Label.TextProperty, "."); testLb.BindingContext = MainText; to testLb.SetBinding(Label.TextProperty, "MainText"); testLb.BindingContext = this; It works!

Refresh ListView on another Content Page via button click event

I am having a hard time refreshing a listView. I've tried using ObservableCollection instead of List for contacts but it didn't help. Can someone points me to the right direction please? Any help would be very much appreciated.
ContactListPage.cs file (This is the default page. Add Contact button loads up NewContactPage.)
public class ContactListPage : ContentPage
{
public ListView listView = new ListView();
public List<Contact> contacts { get; set; }
public ContactListPage()
{
Button button = new Button
{
Text = "Add Contact",
Margin = new Thickness(0, 0, 10, 0)
};
button.Clicked += OnButtonClicked;
StackLayout buttonLayout = new StackLayout { Orientation = StackOrientation.Horizontal, VerticalOptions = LayoutOptions.Center,
Children =
{
new Label {Text = "Contact List", FontSize = 30, FontAttributes = FontAttributes.Bold | FontAttributes.Italic, Margin = new Thickness(10,0,0,0)},
new Label {Text = "", FontSize = 30, FontAttributes = FontAttributes.Bold | FontAttributes.Italic, HorizontalOptions = LayoutOptions.CenterAndExpand},
button
}
};
contacts = new List<Contact>
{
// Add some contacts
new Contact("Jason", "Bourne", "Family"),
new Contact("Sunny", "An", "Family Dog"),
new Contact("Jenny", "Bahn", "Family"),
new Contact("Joshua", "Brown", "Work")
};
// Set up listview
listView.ItemsSource = contacts;
listView.ItemTemplate = new DataTemplate(typeof(TextCell));
listView.ItemTemplate.SetBinding(TextCell.TextProperty, "FullName");
listView.ItemTemplate.SetBinding(TextCell.DetailProperty, "ContactType");
listView.HeightRequest = (40 * contacts.Count);
// Add things to the stacklayout
StackLayout layout = new StackLayout();
layout.Children.Add(buttonLayout);
layout.Children.Add(listView);
Content = layout;
void OnButtonClicked(object sender, EventArgs args)
{
Navigation.PushAsync(new NewContactPage());
};
}
}
Contact.cs file
public class Contact
{
// constructor
public Contact(string firstName, string lastName, string contactType)
{
FirstName = firstName;
LastName = lastName;
ContactType = contactType;
}
// properties
public string FirstName { get; set; }
public string LastName { get; set; }
public string ContactType { get; set; }
public string FullName
{
get
{
return FirstName + " " + LastName;
}
set
{
FullName = value;
}
}
}
NewContactPage.cs file (Save button seems to be working. I've used Debug.WriteLine to see the list of contacts prior and after adding a new contact. Return button suppose to refresh the contactPage.listView.ItemSource with the latest contents of contacts but it doesn't.)
public NewContactPage()
{
ContactListPage contactPage = new ContactListPage();
// Setup tableview
EntryCell firstName = new EntryCell {Label = "First Name:", Keyboard = Keyboard.Default};
EntryCell lastName = new EntryCell {Label = "Last Name:", Keyboard = Keyboard.Default};
EntryCell contactType = new EntryCell {Label = "Contact Type:", Keyboard = Keyboard.Default};
Label firstLabel = new Label { Text = "", FontSize = 10, FontAttributes = FontAttributes.Bold | FontAttributes.Italic, HorizontalOptions = LayoutOptions.CenterAndExpand};
Label secondLabel = new Label {Text = "", FontSize = 10, FontAttributes = FontAttributes.Bold | FontAttributes.Italic, HorizontalOptions = LayoutOptions.CenterAndExpand};
TableView tableView = new TableView {VerticalOptions = LayoutOptions.Start, Intent = TableIntent.Form,
Root = new TableRoot("Table Title") {
new TableSection ("Add a New Contact") {
firstName,
lastName,
contactType
}
}
};
// Setup buttons
Button saveContactButton = new Button {Text = "Save Contact", WidthRequest = 150, Margin = new Thickness(50, 0, 0, 0)};
saveContactButton.Clicked += saveContactButtonClicked;
Button returnButton = new Button {Text = "Return", WidthRequest = 150, Margin = new Thickness(10, 0, 50, 0)};
returnButton.Clicked += returnButtonClicked;
StackLayout buttonLayout = new StackLayout {Orientation = StackOrientation.Horizontal, VerticalOptions = LayoutOptions.Start,
Children =
{
saveContactButton,
new Label {Text = "", FontSize = 30, FontAttributes = FontAttributes.Bold | FontAttributes.Italic, HorizontalOptions = LayoutOptions.CenterAndExpand},
returnButton
}
};
Content = new StackLayout {Children = { tableView, buttonLayout, firstLabel, secondLabel }};
void saveContactButtonClicked(object sender, EventArgs e)
{
try
{
foreach (var yeah in contactPage.contacts)
{
Debug.WriteLine(yeah.FirstName.ToString());
}
// Add new contact to list
contactPage.contacts.Add(new Contact(firstName.Text.ToString(), lastName.Text.ToString(), contactType.Text.ToString()));
foreach (var yeah in contactPage.contacts)
{
Debug.WriteLine(yeah.FullName.ToString());
}
firstName.Text = String.Empty;
lastName.Text = String.Empty;
contactType.Text = String.Empty;
DisplayAlert("Success", "New contact has been added.", "OK");
}
catch(Exception ex)
{
Debug.WriteLine("Exception: {0}", ex);
}
};
void returnButtonClicked(object sender, EventArgs e)
{
contactPage.listView.ItemsSource = null;
contactPage.listView.ItemsSource = contactPage.contacts;
Navigation.PopAsync();
};
}
}
As Jason said, in the constructor of NewContactPage you are creating a new instance of ContactListPage which is completely different than the page you came from (and will return to upon PopAsync()).
To make it so you are adding the new contact to the correct page, I suggest passing in the your ContactListPage in the constructor of the NewContactPage:
public NewContactPage(ContactListPage contactPage)
{
//As a side note it's probably better practice to make
//contactPage a private variable for the NewContactPage class
//...
}
Then in your ContactListPage change the button click method to pass in the page:
void OnButtonClicked(object sender, EventArgs args)
{
Navigation.PushAsync(new NewContactPage(this));
};
Hope this helps!

Issue with FlowListView Xamarin.Forms

I am using FlowListView To set gallery view in my xamarin forms application, with following code..
public class Page1 : ContentPage
{
public Page1()
{
ObservableCollection<ItemModel> List = new ObservableCollection<ItemModel>();
string[] images = {
"https://farm9.staticflickr.com/8625/15806486058_7005d77438.jpg",
"https://farm5.staticflickr.com/4011/4308181244_5ac3f8239b.jpg",
"https://farm8.staticflickr.com/7423/8729135907_79599de8d8.jpg",
"https://farm3.staticflickr.com/2475/4058009019_ecf305f546.jpg",
"https://farm6.staticflickr.com/5117/14045101350_113edbe20b.jpg",
"https://farm2.staticflickr.com/1227/1116750115_b66dc3830e.jpg",
"https://farm8.staticflickr.com/7351/16355627795_204bf423e9.jpg",
"https://farm1.staticflickr.com/44/117598011_250aa8ffb1.jpg",
"https://farm8.staticflickr.com/7524/15620725287_3357e9db03.jpg",
"https://farm9.staticflickr.com/8351/8299022203_de0cb894b0.jpg",
};
int number = 0;
for (int n = 0; n < 20; n++)
{
for (int i = 0; i < images.Length; i++)
{
number++;
var item = new ItemModel()
{
ImageUrl = images[i],
FileName = string.Format("image_{0}.jpg", number),
};
List.Add(item);
}
}
FlowListView listView = new FlowListView()
{
FlowColumnTemplate = new DataTemplate(typeof(ListCell)),
SeparatorVisibility = SeparatorVisibility.None,
HasUnevenRows = true,
FlowColumnMinWidth = 110,
FlowItemsSource = List,
};
listView.FlowItemTapped += (s, e) =>
{
var item = (ItemModel)e.Item;
if (item != null)
{
App.Current.MainPage.DisplayAlert("Alert", "Tapped {0} =" + item.FileName, "Cancel");
}
};
Content = new StackLayout
{
Children = {
listView
}
};
}
}
public class ItemModel
{
public string ImageUrl { get; set; }
public string FileName { get; set; }
}
public class ListCell : View
{
public ListCell()
{
CachedImage IconImage = new CachedImage
{
HeightRequest = 100,
Aspect = Aspect.Fill,
DownsampleHeight = 100,
DownsampleUseDipUnits = false,
LoadingPlaceholder = "image_loading.png",
ErrorPlaceholder = "image_error.png"
};
IconImage.SetBinding(CachedImage.SourceProperty, "ImageUrl");
Label NameLabel = new Label
{
Opacity = 0.5,
HorizontalOptions = LayoutOptions.Fill,
HorizontalTextAlignment = TextAlignment.Center,
VerticalOptions = LayoutOptions.End,
};
NameLabel.SetBinding(Label.TextProperty, "FileName");
Grid grd = new Grid
{
Padding = 3,
ColumnDefinitions = {
new ColumnDefinition { Width = new GridLength (1, GridUnitType.Star) },
},
RowDefinitions = {
new RowDefinition { Height=GridLength.Star},
},
};
grd.Children.Add(IconImage,0,0);
grd.Children.Add(NameLabel, 0, 1);
}
}
i added all the dependency of FlowListView, FFImage etc,
This above code just showing blank screen, Not displaying any data...
You're ListCell has nothing to show.
Append the existing lines to set the content to the grid in your custom ViewCell.
grd.Children.Add(IconImage,0,0);
grd.Children.Add(NameLabel, 0, 1);
Content = grd; <--- add this line
Also have you done the following as per advice from the author? i.e. You've added the nuget library to the platforms in addition to the PCL and added the corresponding initialisation code for the library?
You must add this line to your platform specific project (AppDelegate.cs, MainActivity.cs, etc) before you use FFImageLoading:
CachedImageRenderer.Init();
This is what I got in my IOS:
[Register("AppDelegate")]
public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate
{
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
global::Xamarin.Forms.Forms.Init();
FFImageLoading.Forms.Touch.CachedImageRenderer.Init(); <---- this line
LoadApplication(new App());
return base.FinishedLaunching(app, options);
}
}

ListView Crashing when reloading with my custom cell

I have an app with a Xamarin forms listview that's fed by an ObservableCollection to list user games I fetch from my server. The first time I load it up it works just fine. If I modify that existing ObservableCollection in any way my app crashes with a NullException. I've narrowed it down to my custom ViewCell (GameCell) and I've posted that below. If I comment one line out toward the bottom:
this.SetBinding(IsEnabledProperty, "Enabled");
Then it no longer crashes updating the ObservableCollection, but then I no longer get the functionality to have some cells enabled and some cells disabled. I'm guessing it's trying to set the isEnabled property to a cell that no longer exists because it's been removed on my reload. Any ideas how do this with out crashing? BTW, this works fine on Android, just not on iOS
using System;
using Xamarin.Forms;
using FFImageLoading.Forms;
namespace Upwords
{
public class GameCell : ViewCell
{
public GameCell ()
{
var icon = new CachedImage () {
Aspect = Aspect.AspectFit,
HorizontalOptions = LayoutOptions.Fill,
VerticalOptions = LayoutOptions.Fill,
BackgroundColor = AppStyle.IconColor,
IsVisible = false,
};
icon.SetBinding (CachedImage.SourceProperty, "Icon");
icon.SetBinding (CachedImage.LoadingPlaceholderProperty, "IconPlaceholder");
icon.SetBinding (CachedImage.ErrorPlaceholderProperty, "IconPlaceholder");
icon.SetBinding (CachedImage.WidthRequestProperty, "Height");
icon.SetBinding (CachedImage.HeightRequestProperty, "Height");
icon.Success += (object sender, CachedImageEvents.SuccessEventArgs e) => {
icon.FadeAnimationEnabled = false;
if(icon.Source.GetType() == typeof(Xamarin.Forms.UriImageSource)) {
icon.BackgroundColor = Color.Transparent;
}
};
icon.PropertyChanged += (object sender, System.ComponentModel.PropertyChangedEventArgs e) => {
if(icon.Source != null)
icon.IsVisible = true;
else
icon.IsVisible = false;
};
var nameLabel = new Label () {
FontFamily = "Helvetica",
FontAttributes = FontAttributes.Bold,
FontSize = Device.GetNamedSize (NamedSize.Medium, typeof(Label)),
TextColor = Color.Black,
};
nameLabel.SetBinding (Label.TextProperty, "Name");
//Hide label if it's blank
nameLabel.PropertyChanged += (object sender, System.ComponentModel.PropertyChangedEventArgs e) => {
if(nameLabel.Text == "")
nameLabel.IsVisible = false;
else
nameLabel.IsVisible = true;
};
var detailsLabel = new Label () {
FontFamily = "Helvetica",
FontSize = Device.GetNamedSize (NamedSize.Small, typeof(Label)),
FontAttributes = FontAttributes.Bold,
TextColor = Color.FromHex ("#666"),
IsVisible = false,
};
detailsLabel.SetBinding (Label.TextProperty, "Details");
//Hide label if it's blank
detailsLabel.PropertyChanged += (object sender, System.ComponentModel.PropertyChangedEventArgs e) => {
if(string.IsNullOrEmpty( detailsLabel.Text ) )
detailsLabel.IsVisible = false;
else
detailsLabel.IsVisible = true;
};
var textLayout = new StackLayout {
Padding = new Thickness (5, 0, 0, 0),
Spacing = 0,
HorizontalOptions = LayoutOptions.FillAndExpand,
VerticalOptions = LayoutOptions.CenterAndExpand,
Children = { nameLabel, detailsLabel}
};
var optionSwitch = new Switch() {
HorizontalOptions = LayoutOptions.End,
VerticalOptions = LayoutOptions.Center,
IsVisible = false,
};
optionSwitch.SetBinding (Switch.IsVisibleProperty, "IsSwitch");
var statusLayout = new StackLayout {
Padding = new Thickness (10, 10, 10, 10),
Orientation = StackOrientation.Horizontal,
HorizontalOptions = LayoutOptions.FillAndExpand,
Children = { icon, textLayout, optionSwitch}
};
statusLayout.SetBinding (StackLayout.HeightRequestProperty, "Height");
var separatorBox = new BoxView {
HeightRequest = 1,
HorizontalOptions = LayoutOptions.FillAndExpand,
BackgroundColor = Color.FromRgb(.75,.75,.75),
};
separatorBox.SetBinding (BoxView.HeightRequestProperty, "SeparatorHeight");
var separatorBoxLayout = new StackLayout {
Padding = new Thickness (50, 0, 0, 0),
HorizontalOptions = LayoutOptions.FillAndExpand,
Children = { separatorBox }
};
var cellLayout = new StackLayout {
Spacing = 0,
Padding = new Thickness (0, 0, 0, 0),
Orientation = StackOrientation.Vertical,
HorizontalOptions = LayoutOptions.FillAndExpand,
BackgroundColor = Color.White,
Opacity = 1.0,
Children = { statusLayout, separatorBoxLayout }
};
cellLayout.SetBinding (StackLayout.OpacityProperty, "Opacity");
var headerFrame = new ListViewLabel () {
};
headerFrame.SetBinding (ListViewLabel.IsVisibleProperty, "IsLabel");
headerFrame.SetBinding (ListViewLabel.TextProperty, "Name");
headerFrame.SetBinding (ListViewLabel.HeightRequestProperty, "Height");
headerFrame.PropertyChanged += (object sender, System.ComponentModel.PropertyChangedEventArgs e) => {
if(headerFrame.IsVisible)
cellLayout.IsVisible = false;
else
cellLayout.IsVisible = true;
};
var paddedLayout = new StackLayout {
Spacing = 0,
Orientation = StackOrientation.Horizontal,
HorizontalOptions = LayoutOptions.FillAndExpand,
VerticalOptions = LayoutOptions.FillAndExpand,
Children = { headerFrame, cellLayout }
};
this.SetBinding(IsEnabledProperty, "Enabled");
this.View = paddedLayout;
}
}
public class GameCellData
{
public string Icon { get; set; }
public string IconPlaceholder { get; set; }
public string Name { get; set; }
public string Details { get; set; }
public int Height { get; set; }
public int SeparatorHeight { get; set; }
public bool Enabled { get; set; }
public double Opacity { get; set; }
public bool IsLabel { get; set; }
public bool IsSwitch { get; set; }
}
}
Turns out updating to latest packages fixed the crash.

Resources