Create Listview C# - c#

I need to create a list view programmatically. This list view is populated from a sql server. The labels have their bindings set via a observable collection Shooters. I need this list view to change the number of columns based on a variable called rounds. Everything works as intended but this line of code causes the UI to be messed up.
var con = new CustomViewCell(Rounds);
var connect = await con.GetCellLayout(Rounds); // Returns a grid
var ShooterDataTemplate = new DataTemplate(() =>
{
return new ViewCell { View = connect }; // assigns grid to the viewcell view
});
I get duplicate rows with the same information and other rows are missing their labels. Microsoft called this an inline Data Template. Image below in hyperlink
bad ui
The second options they say is to do it like so..
ShooterListView.ItemTemplate = new DataTemplate(new Typeof(CustomViewCell));
When done this way The UI Looks normal. The problem though is that I cant pass the rounds variable to the customviewcell which determines which function to use to set all the columns.
Here is the exact same grid but done through typeof(CustomViewCell)
Good UI
In both cases I use the exact same grid layout design the only difference is I use inline code to create the data template and then a typeof(customViewCell) how can I get the inline code to not cause such a weird layout design since I cant pass a variable to typeof(CustomViewCell).
Grid code attached below
public async Task<Grid> Get_Round_7_Cell()
{
var column1 = new ColumnDefinition() { Width = new GridLength(15, GridUnitType.Star) };
var column2 = new ColumnDefinition() { Width = new GridLength(15, GridUnitType.Star) };
var column3 = new ColumnDefinition() { Width = new GridLength(10, GridUnitType.Star) };
var column4 = new ColumnDefinition() { Width = new GridLength(10, GridUnitType.Star) };
var column5 = new ColumnDefinition() { Width = new GridLength(10, GridUnitType.Star) };
var column6 = new ColumnDefinition() { Width = new GridLength(10, GridUnitType.Star) };
var column7 = new ColumnDefinition() { Width = new GridLength(10, GridUnitType.Star) };
var column8 = new ColumnDefinition() { Width = new GridLength(10, GridUnitType.Star) };
var column9 = new ColumnDefinition() { Width = new GridLength(10, GridUnitType.Star) };
var smallfont = Device.GetNamedSize(NamedSize.Micro, typeof(Label));
if (Device.Idiom == TargetIdiom.Tablet || Device.Idiom == TargetIdiom.Phone)
{
PaddingLeft = new Thickness(20, 0, 0, 0);
}
else
{
PaddingLeft = new Thickness(60, 0, 0, 0);
}
if (Device.Idiom == TargetIdiom.Tablet || Device.Idiom == TargetIdiom.Phone)
{
PaddingRight = new Thickness(0, 0, 20, 0);
}
else
{
PaddingRight = new Thickness(0, 0, 60, 0);
}
var shooterlabel = new Label() { HorizontalTextAlignment = TextAlignment.Start, FontSize = smallfont, Padding = PaddingLeft };
shooterlabel.SetBinding(Label.TextProperty, new Binding("Shooter_Name"));
var team_name_label = new Label() { HorizontalTextAlignment = TextAlignment.Center, FontSize = smallfont };
team_name_label.SetBinding(Label.TextProperty, new Binding("Team_Name"));
var round1_label = new Label() { HorizontalTextAlignment = TextAlignment.Center, FontSize = smallfont };
round1_label.SetBinding(Label.TextProperty, new Binding("Round_1"));
var round2_label = new Label() { HorizontalTextAlignment = TextAlignment.Center, FontSize = smallfont };
round2_label.SetBinding(Label.TextProperty, new Binding("Round_2"));
var round3_label = new Label() { HorizontalTextAlignment = TextAlignment.Center, FontSize = smallfont };
round3_label.SetBinding(Label.TextProperty, new Binding("Round_3"));
var round4_label = new Label() { HorizontalTextAlignment = TextAlignment.Center, FontSize = smallfont };
round4_label.SetBinding(Label.TextProperty, new Binding("Round_4"));
var round5_label = new Label() { HorizontalTextAlignment = TextAlignment.Center, FontSize = smallfont };
round5_label.SetBinding(Label.TextProperty, new Binding("Round_5"));
var round6_label = new Label() { HorizontalTextAlignment = TextAlignment.Center, FontSize = smallfont };
round6_label.SetBinding(Label.TextProperty, new Binding("Round_6"));
var round7_label = new Label() { HorizontalTextAlignment = TextAlignment.End, FontSize = smallfont, Padding = PaddingRight };
round7_label.SetBinding(Label.TextProperty, new Binding("Round_7"));
grid2.ColumnDefinitions.Add(column1);
grid2.ColumnDefinitions.Add(column2);
grid2.ColumnDefinitions.Add(column3);
grid2.ColumnDefinitions.Add(column4);
grid2.ColumnDefinitions.Add(column5);
grid2.ColumnDefinitions.Add(column6);
grid2.ColumnDefinitions.Add(column7);
grid2.ColumnDefinitions.Add(column8);
grid2.ColumnDefinitions.Add(column9);
grid2.Children.Add(shooterlabel, 0, 0);
grid2.Children.Add(team_name_label, 1, 0);
grid2.Children.Add(round1_label, 2, 0);
grid2.Children.Add(round2_label, 3, 0);
grid2.Children.Add(round3_label, 4, 0);
grid2.Children.Add(round4_label, 5, 0);
grid2.Children.Add(round5_label, 6, 0);
grid2.Children.Add(round6_label, 7, 0);
grid2.Children.Add(round7_label, 8, 0);
grid.Children.Add(boxview);
grid.Children.Add(grid2);
return grid;
}

Solution below. Not the best but its getting the job done. I never could get inline DataTemplate to work so I had to make custom view cells for each round and call them based on what Rounds value was.
public async Task<ListView> SetShooterListView(int Rounds)
{
var shooterlistview = new ListView() { HorizontalOptions = LayoutOptions.Fill };
var headergrid = Rounds == 1 ? await Get_Round_1() : Rounds == 2 ? await Get_Round_2() : Rounds == 3 ? await Get_Round_3() : Rounds == 4 ? await Get_Round_4() : Rounds == 5 ? await Get_Round_5() : Rounds == 6 ? await Get_Round_6() : Rounds == 7 ? await Get_Round_7() : Rounds == 8 ? await Get_Round_8() : Rounds == 9 ? await Get_Round_9() : await Get_Round_10();
var viewcellgrid = Rounds == 1 ? new DataTemplate(typeof(Round_1_View)) : Rounds == 2 ? new DataTemplate(typeof(Round_2_View)) : Rounds == 3 ? new DataTemplate(typeof(Round_3_View)) : Rounds == 4 ? new DataTemplate(typeof(Round_4_View)) : Rounds == 5 ? new DataTemplate(typeof(Round_5_View)) : Rounds == 6 ? new DataTemplate(typeof(Round_6_View)) : Rounds == 7 ? new DataTemplate(typeof(Round_7_View)) : Rounds == 8 ? new DataTemplate(typeof(Round_8_View)) : Rounds == 9 ? new DataTemplate(typeof(Round_9_View)) : new DataTemplate(typeof(Round_10_View));
shooterlistview.Header = headergrid;
shooterlistview.ItemTemplate = viewcellgrid;
return shooterlistview;
}

Related

Remove unwanted spacing between ListView GroupHeaders in Xamarin.Forms

I want to remove the spacing between the group headers in the ListView.
I want to get rid of that space to make my UI more compact.
I tried everything, from setting Spacing=0, RowSpacing=0, ItemSpacing=0 etc. Really don't know what to do now.
This is the list view GroupHeader template and some other settings for the ListView
private void SetListViewDataAsync()
{
string PageTerm = GradesPage.PageTermGlobal;
List<Data> ItemSourceData = Globals.Dataset.FindAll(item => item.TermCode == PageTerm);
listView.ItemsSource = ItemSourceData;
listView.AllowGroupExpandCollapse = true;
listView.Loaded += ListView_Loaded;
listView.PropertyChanged += ListView_PropertyChanged;
listView.GroupExpanding += ListView_GroupExpanding;
listView.GroupCollapsing += ListView_GroupCollapsing;
listView.ItemSpacing = 0;
listView.ItemSize = 200;
listView.GroupHeaderSize = 80;
SetItemTemplate();
listView.DataSource.GroupDescriptors.Add(new GroupDescriptor()
{
PropertyName = "CourseName",
KeySelector = (object obj1) =>
{
var item = (obj1 as Data);
return item;
}
});
listView.GroupHeaderTemplate = new DataTemplate(() =>
{
/*
* Remove mail text, change name to a mailto:
* Remove vertical whitespacing.
*
*/
var MainGrid = new Grid() { VerticalOptions = LayoutOptions.Center, HorizontalOptions = LayoutOptions.FillAndExpand, HeightRequest = 50 };
MainGrid.BackgroundColor = Xamarin.Forms.Color.FromRgba(0, 0, 0, 0.60);
MainGrid.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(1, GridUnitType.Star) });
MainGrid.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(1, GridUnitType.Star) });
MainGrid.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(1, GridUnitType.Star) });
Binding binding1 = new Binding("Key");
binding1.Converter = new GroupHeaderConverter();
binding1.ConverterParameter = 0;
var label = new Label() { VerticalOptions = LayoutOptions.Center, HorizontalOptions = LayoutOptions.Start, FontSize = 17, FontAttributes = FontAttributes.Bold, TextColor = Color.White, Margin = new Thickness(5, 0, 0, 0) };
label.SetBinding(Label.TextProperty, binding1);
Binding binding4 = new Binding("Key");
binding4.Converter = new GroupHeaderConverter();
binding4.ConverterParameter = 3;
var classType = new Label() { VerticalOptions = LayoutOptions.Center, HorizontalOptions = LayoutOptions.Center, FontSize = 10, TextColor = Color.White };
classType.SetBinding(Label.TextProperty, binding4);
var stackLayout = new StackLayout();
stackLayout.Orientation = StackOrientation.Horizontal;
stackLayout.Children.Add(label);
stackLayout.Children.Add(classType);
Binding binding2 = new Binding("Key");
binding2.Converter = new GroupHeaderConverter();
binding2.ConverterParameter = 1;
Frame border = new Frame() { Padding = 0, WidthRequest = 75, HeightRequest = 50, Margin = 10, VerticalOptions = LayoutOptions.CenterAndExpand, HorizontalOptions = LayoutOptions.End };
StackLayout score = new StackLayout() { VerticalOptions = LayoutOptions.CenterAndExpand, HorizontalOptions = LayoutOptions.Center };
Label scoreLabel = new Label() { TextColor = Color.White, FontAttributes = FontAttributes.Bold, VerticalOptions = LayoutOptions.Center, VerticalTextAlignment = TextAlignment.Center };
scoreLabel.SetBinding(Label.TextProperty, binding2);
score.Children.Add(scoreLabel);
Binding binding3 = new Binding("Key");
binding3.Converter = new GroupHeaderConverter();
binding3.ConverterParameter = 2;
border.SetBinding(BackgroundColorProperty, binding3);
border.Content = score;
MainGrid.Children.Add(stackLayout);
Grid.SetColumn(stackLayout, 0);
Grid.SetColumnSpan(stackLayout, 2);
MainGrid.Children.Add(border);
Grid.SetColumn(border, 2);
return MainGrid;
});
}
This is the ListViews ItemTemplate
private void SetItemTemplate()
{
listView.ItemTemplate = new DataTemplate(() => {
SfEffectsView effectsView = new SfEffectsView();
effectsView.TouchDownEffects = SfEffects.Ripple;
effectsView.CornerRadius = new Thickness(25, 0);
var grid = new StackLayout() { VerticalOptions = LayoutOptions.Start };
grid.BackgroundColor = Xamarin.Forms.Color.FromRgba(0, 0, 0, 0.35);
SfListView embeddedView = new SfListView() { VerticalOptions = LayoutOptions.Start };
embeddedView.AutoFitMode = AutoFitMode.Height;
embeddedView.LayoutManager = new GridLayout();
embeddedView.SelectionMode = Syncfusion.ListView.XForms.SelectionMode.None;
embeddedView.LayoutManager.SetBinding(GridLayout.SpanCountProperty, new Binding("NoOfCat"));
embeddedView.SetBinding(SfListView.ItemsSourceProperty, new Binding("CatInfoSet"));
embeddedView.ItemTemplate = new DataTemplate(() => {
var MainGrid = new StackLayout() { VerticalOptions = LayoutOptions.Start };
SfCircularProgressBar circularProgressBar = new SfCircularProgressBar() { VerticalOptions = LayoutOptions.End, HorizontalOptions = LayoutOptions.Center };
circularProgressBar.SetBinding(ProgressBarBase.ProgressProperty, new Binding("Percent"));
circularProgressBar.AnimationDuration = 0;
circularProgressBar.IndicatorOuterRadius = 0.7;
circularProgressBar.IndicatorInnerRadius = 0.6;
Binding bind = new Binding("Percent");
bind.Converter = new ColorGradientConverter();
circularProgressBar.SetBinding(ProgressBarBase.ProgressColorProperty, bind);
Grid content = new Grid();
content.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(1, GridUnitType.Star) });
Label score = new Label() { FontAttributes = FontAttributes.Bold, TextColor = Color.White };
score.BindingContext = circularProgressBar;
Binding scoreBinding = new Binding();
scoreBinding.Path = "Progress";
scoreBinding.StringFormat = "{0}%";
score.SetBinding(Label.TextProperty, scoreBinding);
score.HorizontalTextAlignment = TextAlignment.Center;
score.VerticalOptions = LayoutOptions.Center;
score.TextColor = Color.White;
score.FontSize = 14;
content.Children.Add(score);
circularProgressBar.Content = content;
Label label = new Label() { HorizontalOptions = LayoutOptions.Center, VerticalOptions = LayoutOptions.Start, FontAttributes = FontAttributes.Bold, FontSize = 14, TextColor = Color.White };
label.SetBinding(Label.TextProperty, new Binding("Description"));
MainGrid.Children.Add(circularProgressBar);
MainGrid.Children.Add(label);
return MainGrid;
});
grid.Children.Add(embeddedView);
Label l = new Label() { FontAttributes = FontAttributes.Bold, VerticalOptions = LayoutOptions.End, FontSize = 13, TextColor = Color.White, Margin = new Thickness(5, 0, 0, 0) };
l.SetBinding(Label.TextProperty, new Binding("TeachersName"));
grid.Children.Add(l);
Label l2 = new Label() { FontAttributes = FontAttributes.Italic, VerticalOptions = LayoutOptions.Center, FontSize = 12, TextColor = Color.White, Margin = new Thickness(5, 0, 0, 5) };
Binding periodB = new Binding("Period");
periodB.StringFormat = "Period {0}";
l2.SetBinding(Label.TextProperty, periodB);
grid.Children.Add(l2);
effectsView.Content = grid;
return effectsView;
});
}
Just a feeling:
In your SetListViewDataAsync() method you set:
listView.GroupHeaderSize = 80;
but on the other hand, when you set the value for listView.GroupHeaderTemplate you declare:
var MainGrid = new Grid()
{
VerticalOptions = LayoutOptions.Center,
HorizontalOptions = LayoutOptions.FillAndExpand,
HeightRequest = 50
};
Which means you are telling the ListView that the GroupHeaderSize should be set a value of 80, and next you are telling the GroupeHeaderTemplate that it should be sized to 50, and the view to be vertically centered.
Not sure, but it might be that that extra space you are seeing is just those 80-50=30 units being set as 15 units on top and 15 at the button of your Group header.
If that is the case, there is a number of ways to solve the issue, one of them being simply changing GroupHeaderSize from 80 to 50, that is, changing your code like:
listView.GroupHeaderSize = 50;
Hope this helps!

Xamarin.Forms loading large dataset with Android

I've been working on a Xamarin Forms project and I'm having trouble loading data into the Android application. It loads fine for iOS and UWP, but on Android it takes forever. This is happening on two different screens but I'm assuming the problem is the same. I'm sure there are better ways to load the data than what I am using.
This is the first screen I'm having trouble with on Android (screenshot from UWP):
It loads 15 products in each category into a horizontal scroller. The "See All" link loads all of the products in that category into a vertical scrolling grid. That's the second screen I'm having trouble with.
The code to load this view is:
var scroller = new TLScrollView
{
Orientation = ScrollOrientation.Horizontal,
ItemTemplate = new DataTemplate(() => ViewFactory.Merchandise.Invoke()),
HeightRequest = 320,
Padding = new Thickness(0, 0, 0, 10)
};
scroller.SetBinding(TLScrollView.ItemsSourceProperty, nameof(items));
scroller.ItemsSource = items.OrderByDescending(d => d.Cost).Take(15);
The ViewFactory code is:
public static Func<View> Merchandise { get; } = () =>
{
var mainGrid = new Grid() { WidthRequest = 250, Margin = 5 };
mainGrid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) });
mainGrid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(25, GridUnitType.Absolute) });
mainGrid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(25, GridUnitType.Absolute) });
mainGrid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(25, GridUnitType.Absolute) });
mainGrid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(35, GridUnitType.Absolute) });
var nameLabel = new Label() { Text = "Casket Name", LineBreakMode = LineBreakMode.TailTruncation, HorizontalTextAlignment = TextAlignment.Center };
var materialLabel = new Label() { Text = "MaterialName", HorizontalTextAlignment = TextAlignment.Center };
var costLabel = new Label() { Text = "Cost", HorizontalTextAlignment = TextAlignment.Center };
nameLabel.SetBinding(Label.TextProperty, "ItemName");
materialLabel.SetBinding(Label.TextProperty, "Material");
costLabel.SetBinding(Label.TextProperty, "CostFormatted");
GlobalModel globalModel = App.Current.MainPage.BindingContext as GlobalModel;
var catalogImage = new CachedImage
{
HorizontalOptions = LayoutOptions.FillAndExpand,
VerticalOptions = LayoutOptions.FillAndExpand,
Aspect = Aspect.AspectFit,
LoadingPlaceholder = "MAFSLoader.gif",
CacheDuration = TimeSpan.FromDays(10),
RetryCount = 1,
RetryDelay = 100
};
catalogImage.BindingContextChanged += (s, o) => {
catalogImage.Source = null;
var item = catalogImage.BindingContext as CatalogItem;
if (item == null) return;
catalogImage.Source = item.SmallURL;
};
var buttonStyle = (Style)Application.Current.Resources["ButtonStyle"];
var addToCartButton = new Button { Text = "Add to Cart", BackgroundColor = Color.FromHex("#486E8E"), WidthRequest = 250, Style = buttonStyle };
addToCartButton.SetBinding(Button.CommandParameterProperty, "ItemID");
var imgTapGesture = new TapGestureRecognizer()
{
Command = new Command(() =>
{
if (addToCartButton.CommandParameter == null)
{
addToCartButton.SetBinding(Button.CommandParameterProperty, "ItemId");
}
var dictionary = new Dictionary<string, string>();
dictionary.Add(globalModel.CurrentFuneralHomeKey, addToCartButton.CommandParameter.ToString());
globalModel.ProductDetail.Execute(dictionary);
})
};
catalogImage.GestureRecognizers.Add(imgTapGesture);
addToCartButton.Clicked += new EventHandler(async delegate (Object o, EventArgs a)
{
var button = ((Button)o);
globalModel.AddToCart.Execute(button.BindingContext);
if (button.BindingContext.GetType() == typeof(Data.Corner))
{
await App.Current.MainPage.DisplayAlert("Shopping Cart", "You've added " + (button.BindingContext as Data.Corner).ItemName + " to your cart.", null, "OK");
}
});
mainGrid.Children.Add(catalogImage, 0, 0);
mainGrid.Children.Add(nameLabel, 0, 1);
mainGrid.Children.Add(materialLabel, 0, 2);
mainGrid.Children.Add(costLabel, 0, 3);
mainGrid.Children.Add(addToCartButton, 0, 4);
return mainGrid;
};
If anyone could point me in the right direction I'd be very grateful!
Interesting. I've just gone through the implementation of the TLSrollview. It looks like there is no recycling of elements and maybe lack some optimization (I can see that only if I debug). I see two options :
option 1 : Create a listview with recycling strategy on. For better performance, set also the row height. One item of your listview would be one row. The advantage of a listview is the performance gain from the recycling strategy (especially on Android). Note that on iOS and Android, it might be better to set it on or not.
option 2 : Create a custom layout. That might be a little overkill.

How do I send data back to the parent page in xamarin forms?

There is a label in the page Account which when tapped on will create a new ContentPage with a list of premise addresses. Tapping on any of the addresses should pop the ContentPage and send back a value to the Account page to set certain fields within the Account page. I tried to use Messaging center but it doesn't seem to be able to get the value. What am I missing?
This is the code that creates the ContentPage with the premise addresses:
private void ddlPremisesAddNavigation()
{
PremiseListPage = CreatePAContentPage();
var tgrddlPremiseAddress = new TapGestureRecognizer();
NavigationPage.SetHasNavigationBar(PremiseListPage, false);
tgrddlPremiseAddress.Tapped += (s, e) =>
{
Navigation.PushAsync(PremiseListPage);
};
// ddlPremiseAddresses.GestureRecognizers.Add(tgrddlPremiseAddress);
lblpremiseAddress.GestureRecognizers.Add(tgrddlPremiseAddress);
}
private ContentPage CreatePAContentPage()
{
#region Containers
ContentPage content = new ContentPage();
StackLayout pageContent = new StackLayout();
ScrollView addressesView = new ScrollView()
{
// BackgroundColor = Color.White,
Padding = new Thickness(20, 10, 20, 10)
};
StackLayout addressContainer = new StackLayout();
#endregion
#region Header
RowDefinitionCollection RowDefinitions = new RowDefinitionCollection();
ColumnDefinitionCollection ColumnDefinitions = new ColumnDefinitionCollection();
RowDefinitions.Add(new RowDefinition { Height = new GridLength(50, GridUnitType.Absolute) });
Grid header = new Grid()
{
RowDefinitions = RowDefinitions,
};
BoxView bg = new BoxView() { HeightRequest = 50, WidthRequest = 250, BackgroundColor = Color.White };
header.Children.Add(bg, 0, 0);
Grid.SetColumnSpan(bg, 5);
Label title = new Label()
{
Text = "Premise Address",
FontSize = 15,
FontAttributes = FontAttributes.Bold,
VerticalOptions = LayoutOptions.CenterAndExpand,
HorizontalOptions = LayoutOptions.CenterAndExpand
};
header.Children.Add(title, 1, 0);
Grid.SetColumnSpan(title, 3);
Button back = new Button() { Image = "backArrow", BackgroundColor = Color.White };//
header.Children.Add(back, 0, 0);
Grid.SetColumnSpan(back, 1);
back.Clicked += back_Clicked;
#endregion
#region Address Frames
List<Frame> addrFrames = new List<Frame>();
if (premiseAddresses.Count <= 0)
{
foreach (PremisesModel premise in Premises)
{
premiseAddresses.Add(premise.PremiseId, premise.PremiseAddress);
}
}
foreach (KeyValuePair<int,string> item in premiseAddresses)
{
addrFrames.Add(CreatePAFrame(item));
}
#endregion
#region Add Content to Containers
foreach (Frame item in addrFrames)
{
addressContainer.Children.Add(item);
}
// < Button x: Name = "btnReqAmendment" Text = "Request amendment" Style = "{StaticResource buttonStyle}" Clicked = "btnReqAmendment_Clicked" />
Button addNew = new Button()
{
Text = "ADD NEW PREMISE ADDRESS",
Style = Application.Current.Resources["buttonStyle"] as Style,
HorizontalOptions = LayoutOptions.CenterAndExpand,
Margin = new Thickness(0, 20, 2, 15)
//FontSize = 12,
//WidthRequest = 220,
//HeightRequest = 40
};
addNew.Clicked += btnAddNewPremise_Clicked;
addressContainer.Children.Add(addNew);
addressesView.Content = addressContainer;
pageContent.Children.Add(header);
pageContent.Children.Add(addressesView);
content.Content = pageContent;
#endregion
return content;
}
private Frame CreatePAFrame(KeyValuePair<int, string> premiseAddress)
{
Frame frame = new Frame() { Padding = new Thickness(5, 5, 3, 5), HeightRequest = 60 };
StackLayout content = new StackLayout() { Padding = 0 };
content.Orientation = StackOrientation.Horizontal;
Label pAddress = new Label();
pAddress.Text = premiseAddress.Value;
pAddress.Style = Application.Current.Resources["LabelStart"] as Style;
pAddress.HeightRequest = 50;
pAddress.HorizontalOptions = LayoutOptions.StartAndExpand;
Image img = new Image()
{
Source = "rightArrow",
HorizontalOptions = LayoutOptions.End,
VerticalOptions = LayoutOptions.CenterAndExpand
};
content.Children.Add(pAddress);
content.Children.Add(img);
frame.Content = content;
var selectAddress = new TapGestureRecognizer();
selectAddress.Tapped += (s, e) =>
{
MessagingCenter.Send(this, "premiseId", premiseAddress.Key);
Navigation.PopAsync();
};
frame.GestureRecognizers.Add(selectAddress);
return frame;
}
And this is how it subscribes to Messaging center:
public Account()
{
MessagingCenter.Subscribe<ContentPage,int>(this, "premiseId", (sender,arg) =>
{
DisplayAlert("Premise Changed", "test", "OK");
selectedPremise = arg;
DisplaySelectedPremiseValues();
});
InitializeComponent();
}
One option could be using a global variable (e.g in App.cs) and setting this variable whenever a list item is tapped:
public static Address TappedAddress;
And before showing the listview reset that variable.

Xamarin ViewCell: how to turn off > touch action?

When using ViewCell with TableView it shows a right arrow > (circled in red) and the whole cell can be touched - I suppose to select it and slide a new page from right to left to "drill into details".
Can someone advise on how to disable the display of > ?
Looks that ViewCell.IsEnabled = false turns off the touch action.
Here is some code in my class deriving from ContentPage that creates the table section:
public class SamplePage : ContentPage
{
public SamplePage()
{
var gridLengthStar = new GridLength(1, GridUnitType.Star);
// GRIDSAMPLE CODE
var gridSample = new Grid
{
RowDefinitions =
{
new RowDefinition {Height = GridLength.Auto},
new RowDefinition {Height = GridLength.Auto}
},
Padding = new Thickness(20, 20, 20, 20),
ColumnDefinitions =
{
new ColumnDefinition {Width = gridLengthStar},
new ColumnDefinition {Width = gridLengthStar}
},
};
gridSample.Children.Add ( new Label() { Text = "Data1" }, 0, 0);
gridSample.Children.Add ( new Label() { Text = "Data2" }, 1, 0);
gridSample.Children.Add ( new Label() { Text = "Data3" }, 0, 1);
gridSample.Children.Add ( new Label() { Text = "Data4" }, 1, 1);
var tableView = new TableView
{
HasUnevenRows = true,
Intent = TableIntent.Form,
};
tableView.Root = new TableRoot
{
new TableSection("SECTION TITLE")
{
(new ViewCell {View = gridSample, IsEnabled = false})
}
};
Content = new StackLayout()
{
Children = { tableView } ,
Orientation = StackOrientation.Vertical,
VerticalOptions = LayoutOptions.Start,
Spacing = 10
};
}
}
That arrow can be shown on iOS if you set
Accessory = UITableViewCellAccessory.DisclosureIndicator;
in your UITableViewCell.
Xamarin.Forms usually doesn't set this, so the arrow should not be shown. If it is there, then you have some renderer, Effect or other component which sets it in the iOS code.

Xamarin - Toolbar not displaying on Form

I am having issues with getting a Toolbar displaying on my form. The form is ConfigurationPage.cs. I am including the pages that navigate to the ConfigurationPage and the page itself. Any idea why the Toolbar is not displaying?
App Section
public App()
{
// The root page of your application
MainPage = new NavigationPage(new MainPage());
}
Main Page
public class MainPage : ContentPage
{
public MainPage()
{
BackgroundColor = Color.White;
var setup = new Button
{
Text = "Lane Configuration",
TextColor = Color.Black
};
setup.Clicked += (sender, args) =>
{
Navigation.PushModalAsync(new ConfigurationPage());
};
var gateGridLayout = new Grid
{
Padding = new Thickness(5),
VerticalOptions = LayoutOptions.CenterAndExpand,
HorizontalOptions = LayoutOptions.CenterAndExpand,
RowDefinitions = {new RowDefinition{ Height = new GridLength (1, GridUnitType.Auto) }},
ColumnDefinitions = {new ColumnDefinition{ Width = GridLength.Auto }}
};
gateGridLayout.Children.Add(setup, 0, 0);
Content = gateGridLayout;
}
}
Configuration Page - Toolbar not displaying here
public class ConfigurationPage : ContentPage
{
public event EventHandler SaveToDatabaseCompleted;
public ConfigurationPage()
{
BackgroundColor = Color.White;
var viewModel = new ConfigurationViewModel(this);
BindingContext = viewModel;
var lblIPAddress = new Label
{
Text = "IP Address",
TextColor = Color.Black
};
var IPAddress = new Entry
{
Text = string.Empty,
TextColor = Color.White,
BackgroundColor = Color.Blue,
HorizontalOptions = LayoutOptions.FillAndExpand
};
IPAddress.SetBinding(Entry.TextProperty, "IPAddress");
var lblUserName = new Label
{
Text = "UserName",
TextColor = Color.Black
};
var UserName = new Entry
{
Text = string.Empty,
TextColor = Color.White,
BackgroundColor = Color.Blue,
HorizontalOptions = LayoutOptions.FillAndExpand
};
UserName.SetBinding(Entry.TextProperty, "UserName");
var lblPassword = new Label
{
Text = "Password",
TextColor = Color.Black
};
var Password = new Entry
{
Text = string.Empty,
TextColor = Color.White,
BackgroundColor = Color.Blue,
HorizontalOptions = LayoutOptions.FillAndExpand
};
Password.SetBinding(Entry.TextProperty, "Password");
var lblXml = new Label
{
Text = "XML Page",
TextColor = Color.Black,
};
Picker picker = new Picker
{
Title = "XML Settings",
BackgroundColor = Color.Blue,
VerticalOptions = LayoutOptions.FillAndExpand
};
var options = new List<string> { "val1.xml", "val2.xml" };
foreach (string optionName in options)
{
picker.Items.Add(optionName);
}
string selected = string.Empty;
var lblXMLEntry = new Label
{
Text = "Selected XML Value",
TextColor = Color.Black
};
var XML = new Entry
{
IsEnabled = false,
Text = selected,
TextColor = Color.White,
BackgroundColor = Color.Blue,
HorizontalOptions = LayoutOptions.FillAndExpand
};
XML.SetBinding(Entry.TextProperty, "XML");
picker.SelectedIndexChanged += (sender, args) =>
{
if (picker.SelectedIndex == 0)
selected = picker.Items[0];
else if (picker.SelectedIndex == 1)
selected = picker.Items[1];
XML.Text = selected;
};
var IPAddressLblStack = new StackLayout
{
HorizontalOptions = LayoutOptions.CenterAndExpand,
Orientation = StackOrientation.Horizontal,
Children = {
lblIPAddress
}
};
var UserNameLblStack = new StackLayout
{
HorizontalOptions = LayoutOptions.CenterAndExpand,
Orientation = StackOrientation.Horizontal,
Children = {
lblUserName
}
};
var PasswordLblStack = new StackLayout
{
HorizontalOptions = LayoutOptions.CenterAndExpand,
Orientation = StackOrientation.Horizontal,
Children = {
lblPassword
}
};
var XMLLblStack = new StackLayout
{
HorizontalOptions = LayoutOptions.CenterAndExpand,
Orientation = StackOrientation.Horizontal,
Children = {
lblXml
}
};
var PickerStack = new StackLayout
{
HorizontalOptions = LayoutOptions.CenterAndExpand,
Orientation = StackOrientation.Horizontal,
Children = {
picker
}
};
var XMLLblEntry = new StackLayout
{
HorizontalOptions = LayoutOptions.CenterAndExpand,
Orientation = StackOrientation.Horizontal,
Children = {
lblXMLEntry
}
};
var gateGridLayout = new Grid
{
Padding = new Thickness(5),
VerticalOptions = LayoutOptions.CenterAndExpand,
HorizontalOptions = LayoutOptions.CenterAndExpand,
RowDefinitions = {
new RowDefinition{ Height = new GridLength (1, GridUnitType.Auto) },
new RowDefinition{ Height = new GridLength (1, GridUnitType.Auto) },
new RowDefinition{ Height = new GridLength (1, GridUnitType.Auto) },
new RowDefinition{ Height = new GridLength (1, GridUnitType.Auto) },
new RowDefinition{ Height = new GridLength (1, GridUnitType.Auto) },
new RowDefinition{ Height = new GridLength (1, GridUnitType.Auto) },
new RowDefinition{ Height = new GridLength (1, GridUnitType.Auto) },
new RowDefinition{ Height = new GridLength (1, GridUnitType.Auto) },
new RowDefinition{ Height = new GridLength (1, GridUnitType.Auto) },
new RowDefinition{ Height = new GridLength (1, GridUnitType.Auto) }
},
ColumnDefinitions = {
new ColumnDefinition{ Width = GridLength.Auto }//,
}
};
gateGridLayout.Children.Add(IPAddressLblStack, 0, 1);
gateGridLayout.Children.Add(IPAddress, 0, 2);
gateGridLayout.Children.Add(UserNameLblStack, 0, 3);
gateGridLayout.Children.Add(UserName, 0, 4);
gateGridLayout.Children.Add(PasswordLblStack, 0, 5);
gateGridLayout.Children.Add(Password, 0, 6);
gateGridLayout.Children.Add(XMLLblStack, 0, 7);
gateGridLayout.Children.Add(PickerStack, 0, 8);
gateGridLayout.Children.Add(XMLLblEntry, 0, 9);
gateGridLayout.Children.Add(XML, 0, 10);
var saveButtonToolbar = new ToolbarItem();
saveButtonToolbar.Text = "Save";
saveButtonToolbar.SetBinding(ToolbarItem.CommandProperty, "SaveButtonTapped");
saveButtonToolbar.Priority = 0;
ToolbarItems.Add(saveButtonToolbar);
var cancelButtonToolbar = new ToolbarItem();
cancelButtonToolbar.Text = "Cancel";
cancelButtonToolbar.Command = new Command(async () => await PopModalAsync(true));
cancelButtonToolbar.Priority = 1;
ToolbarItems.Add(cancelButtonToolbar);
Content = gateGridLayout;
}
public void HandleSaveToDatabaseCompleted(object sender, EventArgs e)
{
if (SaveToDatabaseCompleted != null)
SaveToDatabaseCompleted(this, new EventArgs());
}
public async Task PopModalAsync(bool isAnimated)
{
await Navigation.PopModalAsync(true);
}
}
Figured it out. The MainPage setup.clicked event needs to be changed to the below code.
setup.Clicked += async (sender, args) =>
{
await Navigation.PushModalAsync(new NavigationPage(new ConfigurationPage()));
};

Categories