Xamarin - Toolbar not displaying on Form - c#

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()));
};

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!

String.Format is not giving the correct string in Xamarin.Forms

I want to display text in a format in label, but it's displaying an incorrect value.
It's showing the correct value in debug mode. But its displayed wrong on the screen. Ideally, the screen should display total and subtotal as image one.
Code to format string
string paymentFormat = "{0,-25} {1,8}\n";
string paymentMode = "Total"; // Or Subtotal
string paymentAmount = "604.00";
string test = string.Format(paymentFormat, paymentMode, paymentAmount);
Update
public class AlertPopupViewItem : ContentView
{
Label HeaderLabel,MessageLabel;
public Button OKButton, CancelButton;
AbsoluteLayout _overlay;
LoggerService logservice;
public bool ButtonValue = false;
StackLayout CancelStackLayout, OKStackLayout;
string PageSource = string.Empty;
public AlertPopupViewItem()
{
logservice = new LoggerService();
logservice.WriteData(Constants.DEBUG_LOGGING, "Alert Message Popup ctor.. Start");
_overlay = new AbsoluteLayout
{
BackgroundColor = Color.Black.MultiplyAlpha(0.5),
HorizontalOptions = LayoutOptions.Fill,
VerticalOptions = LayoutOptions.Fill,
};
Grid mainGrid = new Grid
{
HeightRequest = 40,
BackgroundColor = Color.White,
Padding = 20,
RowDefinitions =
{
new RowDefinition { Height = new GridLength(15, GridUnitType.Star) },//0 Title
new RowDefinition { Height = new GridLength(3, GridUnitType.Star) },//1 Line
new RowDefinition { Height = new GridLength(80, GridUnitType.Star) },//2 Message
new RowDefinition { Height = new GridLength(12, GridUnitType.Star) },//3 OK-Cancel
}
};
HeaderLabel = new Label
{
FontAttributes = FontAttributes.Bold,
FontSize = 22,
TextColor = Color.Black,
HorizontalTextAlignment= TextAlignment.Center,
VerticalTextAlignment = TextAlignment.Center,
HorizontalOptions = LayoutOptions.CenterAndExpand,
VerticalOptions =LayoutOptions.CenterAndExpand
};
BoxView divider = new BoxView
{
HeightRequest = 1,
Color = Color.Gray,
VerticalOptions = LayoutOptions.End,
};
MessageLabel = new Label
{
FontAttributes = FontAttributes.None,
FontSize = 13,
HorizontalTextAlignment = TextAlignment.Start,
VerticalTextAlignment = TextAlignment.Center,
HorizontalOptions = LayoutOptions.StartAndExpand,
TextColor = Color.Black
};
ScrollView scroll = new ScrollView()
{
Orientation = ScrollOrientation.Vertical
};
scroll.Content = MessageLabel;
Grid ButtonGrid = new Grid
{
HeightRequest = 35,
ColumnDefinitions =
{
new ColumnDefinition {Width=new GridLength(58,GridUnitType.Star) },
new ColumnDefinition {Width=new GridLength(20,GridUnitType.Star) },
new ColumnDefinition {Width=new GridLength(2,GridUnitType.Star) },
new ColumnDefinition {Width=new GridLength(20,GridUnitType.Star) }
}
};
CancelStackLayout = new StackLayout
{
Padding = new Thickness(-6, -6, -6, -6),
//VerticalOptions = LayoutOptions.Center,
BackgroundColor = Color.FromHex("#ff9500")
};
CancelButton = new Button
{
TextColor = Color.White,
FontSize = 15,
BorderRadius = 0,
Text = Localizer.Localize("CancelSmall"),
BackgroundColor = Color.FromHex("#01458e"),
HorizontalOptions =LayoutOptions.FillAndExpand,
VerticalOptions=LayoutOptions.FillAndExpand,
BorderColor = Color.Transparent
};
CancelButton.Clicked += CancelButtonClicked;
CancelStackLayout.Children.Add(CancelButton);
ButtonGrid.Children.Add(CancelStackLayout, 1, 0);
OKStackLayout = new StackLayout
{
Padding = new Thickness(-6, -6, -6, -6),
BackgroundColor = Color.FromHex("#ff9500")
};
OKButton = new Button
{
TextColor = Color.White,
FontSize = 15,
BorderRadius = 0,
Text = Localizer.Localize("OK"),
BackgroundColor = Color.FromHex("#01458e"),
HorizontalOptions = LayoutOptions.FillAndExpand,
VerticalOptions = LayoutOptions.FillAndExpand,
BorderColor = Color.Transparent
};
OKButton.Clicked += OKButtonClicked;
OKStackLayout.Children.Add(OKButton);
ButtonGrid.Children.Add(OKStackLayout, 3, 0);
mainGrid.Children.Add(HeaderLabel, 0, 0);
mainGrid.Children.Add(divider, 0, 1);
mainGrid.Children.Add(scroll, 0, 2);
mainGrid.Children.Add(ButtonGrid, 0, 3);
AbsoluteLayout.SetLayoutFlags(mainGrid, AbsoluteLayoutFlags.All);
AbsoluteLayout.SetLayoutBounds(mainGrid, Findlayoutbounds(new Rectangle(0.20, 0.25, 0.5, 0.50)));
_overlay.Children.Add(mainGrid);
Content = _overlay;
logservice.WriteData(Constants.DEBUG_LOGGING, "Alert Message Popup ctor.. End");
}
// ThreadHandle thread = new ThreadHandle();
private void CancelButtonClicked(object sender, EventArgs e)
{
ButtonValue = false;
this.IsVisible = false;
// thread.WorkMethod();
}
private void OKButtonClicked(object sender, EventArgs e)
{
ButtonValue = true;
if (PageSource == "StarterPage") ;
//MessagingCenter.Send(this, "ModifyValBooleanForAlert");
this.IsVisible = false;
// thread.WorkMethod();
}
Rectangle Findlayoutbounds(Rectangle fractionalRect)
{
if (fractionalRect.Width - 1 == 0)
fractionalRect.Width = 0.99;
if (fractionalRect.Height - 1 == 0)
fractionalRect.Height = 0.99;
Rectangle layoutbounds = new Rectangle
{
X = fractionalRect.X / (1 - fractionalRect.Width),
Y = fractionalRect.Y / (1 - fractionalRect.Height),
Width = fractionalRect.Width,
Height = fractionalRect.Height
};
return layoutbounds;
}
public void DisplayAlertPopup(string alertBoxTitle, string alertBoxContent,bool CancelDisplay)
{
HeaderLabel.IsVisible = false;
CancelStackLayout.IsVisible = CancelDisplay;
CancelButton.IsVisible = CancelDisplay;
HeaderLabel.Text = alertBoxTitle;
MessageLabel.Text = alertBoxContent;
OKButton.Text = Localizer.Localize("OK");
CancelButton.Text = Localizer.Localize("CancelSmall");
HeaderLabel.IsVisible = true;
}
public void DisplayAlertPopup(string alertBoxTitle, string alertBoxContent, string ButtonText)
{
CancelStackLayout.IsVisible = false;
CancelButton.IsVisible = false;
HeaderLabel.Text = alertBoxTitle;
MessageLabel.Text = alertBoxContent;
OKButton.Text = ButtonText;
}
public void DisplayAlertConditionalPopup(string alertBoxTitle, string alertBoxContent, bool CancelDisplay)
{
CancelStackLayout.IsVisible = CancelDisplay;
CancelButton.IsVisible = CancelDisplay;
HeaderLabel.Text = alertBoxTitle;
MessageLabel.Text = alertBoxContent;
this.IsVisible = true;
}
public void SetButtonText(string OKText, string CancelText)
{
if (OKText != null)
OKButton.Text = OKText;
if (CancelText != null)
CancelButton.Text = CancelText;
}
}
I get the formatted string from some other class and call the DisplayAlertPopup method. MessageLabel is the label for which I am setting this value.
Update2:
As suggested in answer, I have tried the below code to set the font for Android. But its also not displying the text in the required format.
MessageLabel = new Label
{
FontAttributes = FontAttributes.None,
FontSize = 13,
HorizontalTextAlignment = TextAlignment.Start,
VerticalTextAlignment = TextAlignment.Center,
HorizontalOptions = LayoutOptions.StartAndExpand,
TextColor = Color.Black,
FontFamily = "Droid Sans Mono"
};
You will need to use a fixed-width font. There is unfortunately none that is built-in across all platforms, but each platform has its own:
iOS - Courier New
Android - Droid Sans Mono
UWP - Consolas
If no built-in font suits you or you want to have the same experience on all platforms, you can also use custom fonts in Xamarin.Forms. This requires you to find a fixed-width font you like on a service like Google Fonts. Then you can follow the tutorial here on Xamarin Help, that describes how to include the TTF file in each platform and use it from XAML.
The short summary is:
Add the font to each platform project with appropriate build action (UWP - Content, iOS - Bundle Resource, Android - Android Asset)
Use the OnPlatform syntax to set the font (ideally creating a static resource so that it can be reused):
Resource:
<OnPlatform x:TypeArguments="x:String" x:Key="MyFontFamily">
<On Platform="Android" Value="MyFont.ttf#Open Sans" />
<On Platform="UWP" Value="/Assets/MyFont.ttf#Open Sans" />
<On Platform="iOS" Value="MyFont" />
</OnPlatform>
And use like this:
<Label FontFamily="{StaticResource MyFontFamily}" />

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 Forms: not displaying created image

I've created a working example for Android and UWP (not tested in iOS) from https://github.com/MitchMilam/Drawit.
I've looked over and over on stackoverflow, but whatever suggestions given, I cannot find the answer.
I'm creating a canvas and I want to show the image in the next screen.
My code for the mainscreen is:
using System;
using System.Collections.Generic;
using System.Linq;
using Xamarin.Forms;
namespace XamarinGame
{
class MainPage : ContentPage
{
private const int PalleteSpacing = 3;
public ImageWithTouch DrawingImage;
private Dictionary<string, Color> ColorPallete;
public MainPage()
{
NavigationPage.SetHasNavigationBar(this, false);
Content = BuildGrid();
// Accomodate iPhone status bar.
Padding = new Thickness(10, Device.OnPlatform(20, 0, 0), 10, 10);
}
private Grid BuildGrid()
{
return new Grid
{
VerticalOptions = LayoutOptions.FillAndExpand,
HorizontalOptions = LayoutOptions.FillAndExpand,
RowDefinitions = {
new RowDefinition {
Height = GridLength.Auto
},
new RowDefinition {
Height = new GridLength (1, GridUnitType.Star)
},
},
ColumnDefinitions = {
new ColumnDefinition {
Width = new GridLength (100, GridUnitType.Absolute)
},
new ColumnDefinition {
Width = new GridLength (1, GridUnitType.Star)
},
},
Children =
{
{new Label {
Text = "Draw It",
Font = Font.BoldSystemFontOfSize (50),
HorizontalOptions = LayoutOptions.CenterAndExpand,
VerticalOptions = LayoutOptions.FillAndExpand
}, 0, 2, 0, 1},
{BuildPalletFrame(), 0, 1},
{new ContentView {
Content = BuildDrawingFrame(),
Padding = new Thickness(10, 0, 0, 0),
HorizontalOptions = LayoutOptions.FillAndExpand,
VerticalOptions = LayoutOptions.FillAndExpand
}, 1, 1}
}
};
}
private StackLayout CreatePalletStack()
{
BuildColorPallete();
var stack = new StackLayout
{
Spacing = PalleteSpacing,
Orientation = StackOrientation.Vertical,
VerticalOptions = LayoutOptions.FillAndExpand
};
stack.SizeChanged += OnStackSizeChanged;
foreach (var button in ColorPallete.Select(color => new Button
{
Text = color.Key,
TextColor = GetTextColor(color.Value),
BackgroundColor = color.Value,
Font = Font.BoldSystemFontOfSize(NamedSize.Medium),
}))
{
button.Clicked += OnButtonClicked;
stack.Children.Add(button);
}
var saveButton = new Button
{
Text = "Save",
};
saveButton.Clicked += OnSaveButtonClicked;
stack.Children.Add(saveButton);
return stack;
}
private void OnSaveButtonClicked(object sender, EventArgs e)
{
Navigation.PushModalAsync(new ShowImage(DrawingImage, "Test"));
}
// Formula for computing Luminance out of R G B, which is something close to luminance = (red * 0.3) + (green * 0.6) + (blue * 0.1).
// Original Source: http://stackoverflow.com/questions/20978198/how-to-match-uilabels-textcolor-to-its-background
private static Color GetTextColor(Color backgroundColor)
{
var backgroundColorDelta = ((backgroundColor.R * 0.3) + (backgroundColor.G * 0.6) + (backgroundColor.B * 0.1));
return (backgroundColorDelta > 0.4f) ? Color.Black : Color.White;
}
private Frame BuildPalletFrame()
{
var palleteFrame = new Frame
{
BackgroundColor = Color.White,
Padding = 5,
Content = CreatePalletStack()
};
return palleteFrame;
}
private Frame BuildDrawingFrame()
{
DrawingImage = new ImageWithTouch
{
VerticalOptions = LayoutOptions.FillAndExpand,
HorizontalOptions = LayoutOptions.FillAndExpand,
BackgroundColor = Color.White,
CurrentLineColor = Color.Black
};
DrawingImage.SetBinding(ImageWithTouch.CurrentLineColorProperty, "CurrentLineColor");
var palleteFrame = new Frame
{
BackgroundColor = Color.White,
Padding = 5,
HasShadow = false,
OutlineColor = Color.Black,
Content = DrawingImage
};
return palleteFrame;
}
private void BuildColorPallete()
{
ColorPallete = new Dictionary<string, Color>
{
{ "White", Color.White },
{ "Silver", Color.Silver },
{ "Gray", Color.Gray },
{ "Yellow", Color.Yellow },
{ "Aqua", Color.Aqua },
{ "Blue", Color.Blue },
{ "Navy", Color.Navy },
{ "Lime", Color.Lime },
{ "Green", Color.Green },
{ "Teal", Color.Teal },
{ "Olive", Color.Olive },
{ "Fuschia", Color.Fuschia },
{ "Red", Color.Red },
{ "Purple", Color.Purple },
{ "Maroon", Color.Maroon },
{ "Black", Color.Black },
};
}
#region Event Handlers
private void OnButtonClicked(object sender, EventArgs e)
{
var button = (Button)sender;
DrawingImage.CurrentLineColor = button.BackgroundColor;
}
private void OnStackSizeChanged(object sender, EventArgs args)
{
var stackLayout = (StackLayout)sender;
var width = stackLayout.Width;
var height = stackLayout.Height;
if (width <= 0 || height <= 0)
{
return;
}
var stackChildSize = height / stackLayout.Children.Count;
var font = Font.BoldSystemFontOfSize(0.4 * stackChildSize);
foreach (var button in stackLayout.Children.Cast<Button>())
{
button.Font = font;
button.HeightRequest = stackChildSize - PalleteSpacing;
}
}
#endregion
}
}
My code for the next screen to load is:
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class ShowImage : ContentPage
{
public ShowImage (Image image, string message)
{
InitializeComponent ();
NewText.Text = "This is a long test " + message;
CreatedImage.Source = image.Source;
}
}
}
The source of the image in the ShowImage is always empty and it's not showing the drawn image. It shows the message I sent.
How can I show the image in the next screen?
Can I convert it to a bytearray or something? FYI: I would like to send it to a (C#) webservice next.
I've tested this on UWP and Android.

How to add TapGestureRecognizer to StackLayout?

So I have this following code:
foreach (var a in abc)
{
var viewCell = new ViewCell
{
View = new StackLayout()
{
//// I want to add TapGestureRecognizer on this outer stacklayout
Padding = new Thickness(20, 0, 20, 0),
HorizontalOptions = LayoutOptions.FillAndExpand,
Children = {
new StackLayout() {
Orientation = StackOrientation.Horizontal,
VerticalOptions = LayoutOptions.CenterAndExpand,
Children = {
new StackLayout() {
HorizontalOptions = LayoutOptions.StartAndExpand,
Children = {
new Label { Text = a.Name}}
},
new StackLayout() {
HorizontalOptions = LayoutOptions.EndAndExpand,
Orientation = StackOrientation.Horizontal,
Children = {
new Label { Text = a.Count},
new Image { Source = "right1.png" }
}
}
}
}
}
}
};
tableSection.Add(viewCell);
}
What this code basically do is repeat the rows(ViewCell) of my TableView depending on the number of objects in the abc. I want to add a tap event on the outer (first Stacklayout) but I can't seem to find out how to do it with my how my ViewCell is set up. Anyone has any idea?
You should create your StackLayout in a variable first and then add a TapGestureRecognizer to it:
foreach (var a in abc)
{
var stackLayout = new StackLayout()
{
//// I want to add TapGestureRecognizer on this outer stacklayout
Padding = new Thickness(20, 0, 20, 0),
HorizontalOptions = LayoutOptions.FillAndExpand,
Children = {
new StackLayout() {
Orientation = StackOrientation.Horizontal,
VerticalOptions = LayoutOptions.CenterAndExpand,
Children = {
new StackLayout() {
HorizontalOptions = LayoutOptions.StartAndExpand,
Children = {
new Label { Text = a.Name}}
},
new StackLayout() {
HorizontalOptions = LayoutOptions.EndAndExpand,
Orientation = StackOrientation.Horizontal,
Children = {
new Label { Text = a.Count},
new Image { Source = "right1.png" }
}
}
}
}
}
};
var tgr = new TapGestureRecognizer();
tgr.Tapped += (s,e) => OnTgrClicked();
stackLayout.GestureRecognizers.Add(tgr);
var viewCell = new ViewCell
{
View = stackLayout;
};
tableSection.Add(viewCell);
}

Categories