Why when I try to set ActionBar.CustomView.SetBackgroundColor (Color.White); Does the application crash? - xamarin

Why when I try to set ActionBar.CustomView.SetBackgroundColor (Color.White); Does the application crash?
I tried installing the ToolbarItems background via style, toolbar.axml via ResourceDictionary but not one of these methods works for me - I think because I'm too dumb.
Now this option is the easiest for me, since there is only one line of code, but somewhere you can see the conflict comes from style or toolbar.axml or something else.
ActionBar.CustomView.SetBackgroundColor (Color.White);
my app.xaml.cs
using System;
using System.IO;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
using MyApp1.Services;
using MyApp1.Views;
namespace MyApp1
{
public partial class App : Application
{
static Data.TodoItemDatabase database;
public App()
{
InitializeComponent();
MainPage = new AppShell();
}
protected override void OnStart()
{
// Handle when your app start
}
protected override void OnSleep()
{
// Handle when your app sleeps
}
protected override void OnResume()
{
// Handle when your app resumes
}
public static Data.TodoItemDatabase Database
{
get
{
if (database == null)
{
database = new Data.TodoItemDatabase(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "TodoSQLite.db3"));
}
return database;
}
}
public int ResumeAtTodoId { get; set; }
}
}

Solution 1:
You can set the style of TitleView in Forms . You can create a base Navigation Pageand set the style of TitleView
<NavigationPage.TitleView>
<StackLayout Orientation="Horizontal" BackgroundColor="White" >
//...
</StackLayout>
</NavigationPage.TitleView>
Solution 2
You can try creating a Custom Renderer and set it as the base class for all pages in the app. Within this custom renderer you can try to set the background color and other style as you want in CustomTitleView .
[assembly: ExportRenderer(typeof(Page), typeof(AndroidNavigationPageRenderer )]
public class AndroidNavigationPageRenderer : PageRenderer
{
private CustomTitleView _titleView;
public NavigationSearchRenderer(Context context) : base(context)
{
}
protected override void OnElementChanged(ElementChangedEventArgs<Page> e)
{
base.OnElementChanged(e);
var activity = this.Context as FormsAppCompatActivity;
if (activity == null)
return;
var toolbar = activity.FindViewById<Android.Support.V7.Widget.Toolbar>(Resource.Id.toolbar);
_titleView= new TitleView(Context);
toolbar.AddView(_titleView);
}
}

Related

Binding text label on a home page to a timer

We have a really simple app, the idea is the timer will update a label on the home screen depending on different configuration within the mobile app. I have created the binding and can update the homepage from it's self but not from the timer. I think what is missing is a OnChange within the home page to detect if the string has changed.
Display layout code, bind the label to the name "LabelText"
<Label
Text = "{Binding LabelText, Mode=TwoWay}"
x:Name="MainPageStatusText"
HorizontalOptions="CenterAndExpand"
Grid.Row="2"
Grid.Column="0"
Grid.ColumnSpan="6"
VerticalOptions="CenterAndExpand"
TextColor="White"
FontSize="Medium"/>
This is the class file to link the text string to the label, I can see it been called from the different places but when it's called from the app.cs it does not work
using System;
using System.Collections.Generic;
using System.ComponentModel;
using Xamarin.Forms;
namespace Binding_Demo
{
public class MyClass : INotifyPropertyChanged
{
protected void OnPropertyChanged(PropertyChangedEventArgs e)
{ PropertyChanged?.Invoke(this, e); }
protected void OnPropertyChanged(string propertyName)
{ OnPropertyChanged(new PropertyChangedEventArgs(propertyName)); }
public event PropertyChangedEventHandler PropertyChanged;
private string labelText;
public string LabelText
{
get {
return labelText;
}
set
{
labelText = value;
OnPropertyChanged("LabelText");
}
}
}
}
This is the code inside the homepage, this works and I can see it sending data to the text label
public static MyClass _myClass = new MyClass();
public Homepage()
{
BindingContext = _myClass;
_myClass.LabelText = "Inside the home page";
}
This is the App.cs code, we start the timer and then want to set the text on the Homepage label. I can see the class been called, but it does not set the text.
using System;
using System.Diagnostics;
using System.Threading.Tasks;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace Binding_Demo
{
public partial class App : Application
{
public static MyClass _myClass = new MyClass();
public App()
{
//InitializeComponent();
Device.StartTimer(TimeSpan.FromSeconds(10), () =>
{
Task.Run(() =>
{
Debug.WriteLine("Timer has been triggered");
// !!!!! This is not setting the text in the label !!!!!
BindingContext = _myClass;
_myClass.LabelText = "Inside the timer app";
});
return true; //use this to run continuously
});
MainPage = new NavigationPage(new MainPage());
}
protected override void OnStart()
{
//
}
protected override void OnSleep()
{
}
protected override void OnResume()
{
// force app to mainpage and clear the token
}
}
}
I have created the binding and can update the homepage from it's self but not from the timer.
As Jason said, please make sure the binding model is unique. You could create a global static instance of MyClass in App class, then bind this instance to HomePage.
Check the code:
App.xaml.cs
public partial class App : Application
{
public static MyClass _myClass = new MyClass();
public App()
{
InitializeComponent();
Device.StartTimer(TimeSpan.FromSeconds(5), () =>
{
Task.Run(() =>
{
_myClass.LabelText = "Inside the timer app";
});
return true;
});
MainPage = new NavigationPage(new Homepage());
}
}
Homepage.xaml.cs:
public Homepage()
{
InitializeComponent();
BindingContext = App._myClass;
}

My UI did not response for orientation change

I am developing a native mobile app for all platforms. I have created my own theme content page. Then after deployment on android when I make phone landscape it did not respond. what's the reason here.
Here is my base content page.
public abstract class BaseContentPage : ContentPage
{
public readonly BaseViewModel BaseViewModel;
protected bool _isNavigated = false;
public BaseContentPage(BaseViewModel baseViewModel)
{
BaseViewModel = baseViewModel;
}
public abstract void Navigate(SelectedItemChangedEventArgs e);
protected abstract override void OnAppearing();
protected override void OnDisappearing()
{
_isNavigated = true;
}
public BaseContentPage()
{
}
}
here Xaml
<views:BaseContentPage
xmlns:views="clr-namespace:DipsDemoXaml.Views"
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:Resource="clr-namespace:DipsDemoXaml.Resources"
x:Class="DipsDemoXaml.Views.WardListPage" Title="{x:Static Resource:AppResources.WardListPageTitle}">
<StackLayout BackgroundColor="{StaticResource DefaultBackgroundColor}" Orientation="Vertical" x:Name="s1">
I even try this also in code behind constructor I call size changed and create a method called Wardpagesizechanged.
public WardListPage(WardListPageViewModel wardListViewModel) : base(wardListViewModel)
{
InitializeComponent();
this.SizeChanged += wardpagesizechanged;
}
Wardpagesizechanged method
private void wardpagesizechanged(object sender, EventArgs e)
{
if(this.Width> this.Height)
{
s1.Orientation = StackOrientation.Horizontal;
}
else
{
s1.Orientation = StackOrientation.Vertical;
}
}
what is the problem here, I am clueless

Xamarin forms - How do I set font for toolbaritems

I have a toolbar in my mainpage and would like to set the font for each toolbaritem (so I can set custom fonts or normal fonts). So far I have been trying to get this done by implementing my own effect and this code works for labels but not for toolbaritems.
Whenever I run this code the effects gets added to the toolbaritem, but the effect code in android doesn't get called.
Does anyone know why I am unable to set fonts for toolbaritems with effects?
GitHub: https://github.com/jashan07/CustomEffectTest
Edit:
Brad Dixon suggested using TitleView which allows me to place labels in my navigationbar. As mentioned before the effect works for every control except toolbaritems.
This is a workaround which works for now (don't know about the limits or effects this will have) but I am still wondering why this isn't working for toolbaritems.
(TitleView was introduced in Xamarin.Forms V3.2)
My effect class:
public static class ChangeFontEffect
{
public static readonly BindableProperty FontProperty = BindableProperty.CreateAttached("Font",
typeof(string),
typeof(ChangeToolbarFontEffect),
null, propertyChanged: OnFontChanged);
private static void OnFontChanged(BindableObject bindable, object oldValue, object newValue)
{
if(bindable is Label labelControl)
{
if (!labelControl.Effects.Any((e) => e is ChangeToolbarFontEffect))
labelControl.Effects.Add(new ChangeToolbarFontEffect());
}
else if(bindable is ToolbarItem toolbarItem)
{
if (bindable is ToolbarItem)
if (!toolbarItem.Effects.Any((e) => e is ChangeToolbarFontEffect))
toolbarItem.Effects.Add(new ChangeToolbarFontEffect());
}
return;
}
public static string GetFont(BindableObject view)
{
return (string)view.GetValue(FontProperty);
}
public static void SetFont(BindableObject view, string value)
{
view.SetValue(FontProperty, value);
}
class ChangeToolbarFontEffect : RoutingEffect
{
public ChangeToolbarFontEffect() : base("CustomEffectTest.ChangeToolbarFontEffect") { }
}
}
XAML
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:effects="clr-namespace:CustomEffectTest.Effects"
x:Class="CustomEffectTest.MainPage">
<ContentPage.ToolbarItems>
<ToolbarItem Text="normal text"></ToolbarItem>
<ToolbarItem Text="ﭗ" effects:ChangeFontEffect.Font="materialdesignicons-webfont.ttf"></ToolbarItem>
</ContentPage.ToolbarItems>
Android
[assembly: ResolutionGroupName("bottomNavTest")]
[assembly: ExportEffect(typeof(ChangeToolbarFontEffect), "ChangeToolbarFontEffect")]
namespace bottomNavTest.Droid
{
public class ChangeToolbarFontEffect : PlatformEffect
{
TextView control;
protected override void OnAttached()
{
try
{
control = Control as TextView;
Typeface font = Typeface.CreateFromAsset(Forms.Context.ApplicationContext.Assets, ChangeFontEffect.GetTextFont(Element));
control.Typeface = font;
}
catch(Exception e)
{
}
}
protected override void OnDetached()
{
}
protected override void OnElementPropertyChanged(PropertyChangedEventArgs args)
{
if (args.PropertyName == ChangeFontEffect.TextFontProperty.PropertyName)
{
var val = ChangeFontEffect.GetTextFont(Element);
if (val != null)
{
Typeface font = Typeface.CreateFromAsset(Forms.Context.ApplicationContext.Assets, ChangeFontEffect.GetTextFont(Element));
control.Typeface = font;
}
}
}
}
}

Removing back swipe gesture from page using xamarin forms

Is there a way i can disable the back swipe to previous page option for iOS on one single page of my project ?
You can achieve this by implementing a custom renderer and setting the right property for this. You can see a sample implementation underneath. The right property, in this case, is InteractivePopGestureRecognizer which you need to set to false.
Do this in the ViewWillAppear so the NavigationController is initialized.
using DisableSwipe.iOS;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;
[assembly: ExportRenderer(typeof(ContentPage), typeof(NoBackSwipeRenderer))]
namespace DisableSwipe.iOS
{
public class NoBackSwipeRenderer : PageRenderer
{
public override void ViewWillAppear(bool animated)
{
base.ViewWillAppear(animated);
if (ViewController?.NavigationController != null)
ViewController.NavigationController.InteractivePopGestureRecognizer.Enabled = false;
}
}
}
#Symorp
You could do it like so:
public class YourCustomPageRenderer : PageRenderer
{
private YourCustomPage _yourCustomPage;
protected override void OnElementChanged(VisualElementChangedEventArgs e)
{
base.OnElementChanged(e);
_yourCustomPage = e.NewElement as YourCustomPage;
if (_yourCustomPage != null)
{
_yourCustomPage.PropertyChanged += YourCustomPagePropertyChangedEventHandler;
}
}
public override void ViewWillAppear(bool animated)
{
base.ViewWillAppear(animated);
SetInteractivePopGestureRecognizerEnabled(isEnabled: false);
}
private void YourCustomPagePropertyChangedEventHandler(object sender, PropertyChangedEventArgs propertyChangedEventArgs)
{
if (propertyChangedEventArgs.PropertyName == nameof(YourCustomPage.IsInteractivePopGestureRecognizerEnabled))
{
SetInteractivePopGestureRecognizerEnabled(_yourCustomPage.IsInteractivePopGestureRecognizerEnabled);
}
}
private void SetInteractivePopGestureRecognizerEnabled(bool isEnabled)
{
var interactivePopGestureRecognizer = ViewController?.NavigationController?.InteractivePopGestureRecognizer;
if (interactivePopGestureRecognizer != null)
{
//Prevents the back-swipe-gesture when the user wants to swipe a page away (from left edge of the screen)
interactivePopGestureRecognizer.Enabled = isEnabled;
}
}
}
public class YourCustomPage : ContentPage
{
/// <summary>
/// If you need it as bindable property, feel free to create a <see cref="BindableProperty"/>.
/// </summary>
public bool IsInteractivePopGestureRecognizerEnabled { get; set; }
}
Feel free to adjust to your needs! :-)
I omitted the export renderer attribute etc., just for simplicity.

Xamarin white screen in local machine

enter image description here
Hello,
I have a problem with Xamarin, when i run program i see only white screen, just like on picture.
MainPage.xaml.cs have this code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Xamarin.Forms;
namespace Hello
{
public class App : Application
{
public App()
{ // The root page of your application
MainPage = new ContentPage
{
Content = new StackLayout
{
VerticalOptions = LayoutOptions.Center,
Children = {
new Label {
HorizontalTextAlignment = TextAlignment.Center,
Text = "Welcome to Xamarin Forms!"
}
}
}
};
}
protected override void OnStart()
{
// Handle when your app starts
}
protected override void OnSleep()
{
// Handle when your app sleeps
}
protected override void OnResume()
{
// Handle when your app resumes
}
}
}
I take this code from "Creating Mobile Apps with Xamarin Forms", somebody know what is wrong with this program?
Write your code in Shared project's App.xaml.cs class which is partial class. The code above you are showing is not partial class. Probably, as your screenshot showing you have written App class code in Main.axml.cs file
using System;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
[assembly: XamlCompilation(XamlCompilationOptions.Compile)]
namespace App
{
public partial class App : Application
{
public App()
{
InitializeComponent();
//MainPage = new MainPage();
MainPage = new ContentPage
{
Content = new StackLayout
{
VerticalOptions = LayoutOptions.Center,
Children =
{
new Label
{
HorizontalTextAlignment=TextAlignment.Center,
Text="Welcome to xamarin forms"
}
}
}
};
}
}
}

Resources