I'm just starting out in xamarin forms, right now I'm trying to make it so both the titlebar and navbar for my pages change colour depending on what page you're on. I also have the toolbarposition set to bottom.
The problem is changing the colour only changes the bottom navigation bar, not the top title bar.
My mainpage (the tabbed page) code behind
public partial class MainPage : TabbedPage
{
public MainPage()
{
On<Android>().SetToolbarPlacement(ToolbarPlacement.Bottom);
InitializeComponent();
this.BarBackgroundColor = Color.FromHex("#008B8B");
this.BarTextColor = Color.White;
}
}
This changes my navigation bar at the bottom to the colour I want, but leaves the top title bar the default blue colour.
Budget & Expenses are two generic content pages (as you can see)
If you have not set the page title, then correct it would be blank. To set the color of the title bar at the top for each page, I've used navigation pages for each tabbed page child, then set the background color of those navigation pages
Example: The xaml for your app's main page
<controls:TabbedPage
xmlns:controls="clr-namespace:bla.Controls" xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="bla.Views.HomePage"
>
<controls:TabbedPage.Children>
<NavigationPage BarTextColor="White" Title="Home" Icon="home.png" Padding="0,-12,0,0">
<x:Arguments>
<HomePage/>
</x:Arguments>
</NavigationPage>
<NavigationPage Title="Communities" BarTextColor="White" Icon="people_outline.png">
<x:Arguments>
<OtherPage />
</x:Arguments>
</NavigationPage>
</controls:TabbedPage.Children>
Your app.xaml:
MainPage = GetMainPage();
MainPage.SetValue(NavigationPage.BarBackgroundColorProperty, Color.Green);
public static Page GetMainPage()
{
return new HomePage(); //home page is a tabbed page
}
You could use static resources in your App.xaml for the style of your NavigationPage for all the project solution.
Paste this code in your App.xaml
<Application.Resources>
<Style TargetType="NavigationPage">
<Setter Property="BarBackgroundColor" Value="Color of Bar Background" />
<Setter Property="BarTextColor" Value="Color of your text on you Bar" />
</Style>
<Application.Resources>
This line is that answers your problem.
<Setter Property="BarTextColor" Value="Color of your text on you Bar" />
I hope it helped you...
Related
I am working with Xamarin Forms creating both Android and iOS application. I have tabbed page - at Android tabbed page is being shown at top and when I have a lot of tabs, not all of them are being shown, but they can be slided in horizontal direction.
At iOS when I have more than 5 tabs, then there is a "more button" created, that I can open and see rest of tabs.
How to delete "more" button when have more than 5 tabs at iOS tabbed page and put slideable tabs (similar to android) ?
You can use Naxam.TopTabbedPage.Forms from Nuget
Usage:
in your iOS project AppDelegate.cs file
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
global::Xamarin.Forms.Forms.Init();
TopTabbedRenderer.Init(); //add this line
LoadApplication(new App());
return base.FinishedLaunching(app, options);
}
And in your forms
in xaml
<?xml version="1.0" encoding="utf-8" ?>
<forms:TopTabbedPage
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:App11"
x:Class="App11.MainTabbedPage"
xmlns:forms="clr-namespace:Naxam.Controls.Forms;assembly=Naxam.TopTabbedPage.Forms"
BarBackgroundColor="#2196F3">
<local:Page1 Title="PAGE 1"/>
<local:Page2 Title="PAGE 2"/>
<local:Page3 Title="PAGE 3"/>
<local:Page4 Title="PAGE 4"/>
<local:Page5 Title="PAGE 5"/>
</forms:TopTabbedPage>
in xaml.cs
using Naxam.Controls.Forms;
namespace TopTabbedPageDemo
{
public partial class MainTabbedPage : TopTabbedPage
{
public MainTabbedPage()
{
InitializeComponent();
}
}
}
Is it possible to move first tab title starting position that it is not cut in half? the problem happens only if there are a lot of tabs. After moving between tabs the problem disapears, but when page is initialize it happens.
Try to setup the CurrentPage to the corresponding Content Page;
i.e;
if you want 1st contentpage to display while initialization set as;
this.CurrentPage = tab1; // where tab1 is the x:Name for the contentpage
hope it helps;
thanks
This would seem to be really simple (and probably is), but I just can't seem to find any information about this.
Take a look at:
There is a full width white gap on top. What is it? How do I get rid of it or access it (add text, buttons, icons, etc)?
For this test, my code is super simple. 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:maps="clr-namespace:Xamarin.Forms.Maps;assembly=Xamarin.Forms.Maps"
x:Class="TestApp.TestPage">
<StackLayout VerticalOptions="FillAndExpand" Padding="0">
<maps:Map x:Name="TestMap" IsShowingUser="true" MapType="Street" />
</StackLayout>
</ContentPage>
.cs:
using Xamarin.Forms;
namespace Test
{
public partial class TestPage : ContentPage
{
public TestPage()
{
InitializeComponent();
}
}
}
app.xaml:
<ResourceDictionary>
<Style TargetType="NavigationPage">
<Setter Property="BarBackgroundColor" Value="White"/>
<Setter Property="BarTextColor" Value="Black"/>
</Style>
<Style x:Key="DefaultPageStyle" TargetType="ContentPage">
<Setter Property="BackgroundColor" Value="White"/>
</Style>
</ResourceDictionary>
Edit: The comment from #Vulcan Lee, sent me on a path to finding the missing (key) information.
Which was, inside App.xaml.cs, I had:
public App()
{
InitializeComponent();
MainPage = new NavigationPage(new TestPage());
}
So, this has to do with the navigation menu. How do I access, format or remove it?
The white space is actually navigation bar.
Change this:
new NavigationPage(new TestPage())
to
new TestPage()
Or just remove the navigation bar if you still want to make the first page as a navigation page:
NavigationPage.SetHasNavigationBar(this, false);
I remember this change is introduced in Xamarin.Forms 2.3.x.
You can try setting the map to VerticalOptions="FillAndExpand". It will not have much effect on the StackLayout because the StackLayout just wants to be what ever size it's children are. If setting the map's VerticalOptions does not work, you could instead set it's HeightRequest property manually.
If all that fails, I would suggest putting the map into a Grid instead.
Say I want an Entry element to not have auto-correct or auto-capitalize. This can be done by setting its Keyboard property like so:
new Entry { Keyboard = Keyboard.Create(0) }
Now, how do I make that the global default for all Entry elements?
I know I can create a custom element that inherits from the built-in element, and override the property that way, like:
public class EntryCustom : Entry
{
public EntryCustom()
{
Keyboard = Keyboard.Create(0);
}
}
and then simply call it like:
new EntryCustom { ... }
But is there a way to do this directly on the built-in element type, without creating a custom element type?
You can do this by saving the custom keyboard into a static and then binding it to all Entry fields using a default style. You can place that default style into an application-wide resource dictionary, which is automatically applied throughout the application. Here is sample code that I just tested to verify in a new empty Forms project:
Step 1. Save the custom keyboard into a static.
Keyboards.cs (static custom keyboard):
using Xamarin.Forms;
namespace KeyboardDemo
{
public static class Keyboards
{
public static Keyboard Unassisted { get; private set; }
static Keyboards ()
{
Unassisted = Keyboard.Create (0);
}
}
}
Step 2. Create an App.xaml for your project.
Follow this tip to add an App.xaml to your Forms project: http://jfarrell.net/2015/02/02/centralize-your-styles-with-xamarin-forms/
Step 3. Add the default style to App.xaml
App.xaml:
<?xml version="1.0" encoding="UTF-8"?>
<Application
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:demo="clr-namespace:KeyboardDemo"
x:Class="KeyboardDemo.App">
<Application.Resources>
<ResourceDictionary>
<Style x:Key="EntryStyle" TargetType="Entry">
<Setter Property="Keyboard" Value="{x:Static demo:Keyboards.Unassisted}" />
</Style>
<Style BasedOn="{StaticResource EntryStyle}" TargetType="Entry" />
</ResourceDictionary>
</Application.Resources>
</Application>
Step 4. Add a new page to the project
Add a ContentPage to the application, with plain Entry controls to verify the styling.
App.xaml.cs:
using Xamarin.Forms;
namespace KeyboardDemo
{
public partial class App : Application
{
public App ()
{
InitializeComponent ();
MainPage = new MyPage ();
}
}
}
MyPage.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"
x:Class="KeyboardDemo.MyPage">
<ContentPage.Padding>
<OnPlatform x:TypeArguments="Thickness" iOS="0,20,0,0" Android="0" WinPhone="0" />
</ContentPage.Padding>
<StackLayout>
<Entry />
</StackLayout>
</ContentPage>
*Edit: Coming back to this answer after gaining some new found XAML knowledge and figuring out how to do this all from XAML!
See below for adding the Keyboard with KeyboardFlags to a Style using only XAML.
Also see here for available KeyboardFlag values. I am just using None below.
<ContentPage.Resources>
<ResourceDictionary>
<Keyboard x:Key="NoCapitalizationKeyboard"
x:FactoryMethod="Create">
<x:Arguments>
<KeyboardFlags>None</KeyboardFlags>
</x:Arguments>
</Keyboard>
<Style x:Key="NoCapitalizationEntryStyle"
TargetType="Entry">
<Setter Property="Keyboard"
Value="{StaticResource NoCapitalizationKeyboard}">
</Style>
<Style BasedOn="{StaticResource NoCapitalizationEntryStyle}"
TargetType="Entry" />
</ResourceDictionary>
</ContentPage.Resources>
<Entry />
-- Old Answer --
Unfortunately I do not think you can do that with Global Styles, since you can only set the Keyboard to one of the predefined keyboard sets listed here as opposed to being able to individually turn specific functionality on and off.
Another option would be to create a custom renderer for the Entry control itself and then implement code to turn it off in each platform. Something like this for iOS (except I think you would use Control.AutocapitalizationType = UITextAutocapitalizationType.None;).
I currently have all my styles in my App.xaml file. Is there a way to group them as a theme so I can multiple app themes and change at will?
As I know there is no built-in theming support in Xamarin.Forms but you can implement one.
That you will need to do:
1. Add a number of ResourceDictionaries to your App.xaml with identical list of styles.
<Application
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="ThemeTest.App">
<Application.Resources>
</Application.Resources>
<ResourceDictionary x:Name="Default">
<Style x:Key="labelStyle" TargetType="Label">
<Setter Property="TextColor" Value="Green" />
</Style>
</ResourceDictionary>
<ResourceDictionary x:Name="Second">
<Style x:Key="labelStyle" TargetType="Label">
<Setter Property="TextColor" Value="Yellow" />
</Style>
</ResourceDictionary>
</Application>
2. In your App.xaml.cs add code to switch between styles.
public partial class App : Application
{
public App()
{
InitializeComponent();
SetDefaultStyle();
MainPage = new TestPage();
}
public void SetDefaultStyle()
{
Resources = Default;
}
public void SetSecondStyle()
{
Resources = Second;
}
}
3. In XAML reference your style using DynamicResource markup extension.
<Label Text="Test text" Style="{DynamicResource labelStyle}" />
I created sample application which you can find here.
Shell you have any questions you are welcome to ask.
An alternative solution is substituting resources on app start/view initialization. In case you already have a project with Styles and StaticResource references sprawling out for entire project, rather than going and updating all references to DynamicResource, you can create a second XAML dictionary with styles for your theme. One drawback, it might require reloading the app.
E.g. you can have you default theme in App.xaml global resources and white theme style overrides in WhiteTheme.xaml. On creation of the view you can check if the theme is not default (e.g. via App.Current.Properties.ContainsKey(nameof(WhiteTheme) ), iterate through all keys in non-default resource dictionary and put/replace with them keys in default dictionary:
public partial class MainPage : ContentPage
{
public MainPage()
{
ApplyTheme();
InitializeComponent();
}
private static void ApplyTheme()
{
if ((App.Current as App).WhiteTheme)
{
var whiteTheme = new WhiteTheme();
foreach (var key in whiteTheme.Keys)
{
if (Application.Current.Resources.ContainsKey(key))
Application.Current.Resources[key] = whiteTheme[key];
}
}
}
}
Here're the examples of App.xaml, WhiteTheme.xaml and MainPage.xaml.cs.
I'm using Resource Dictionaries a lot, but it's getting tedious having to copy and paste them from one Xaml to the other to have them all update. The only way I've seen this done is inheriting a style class, but I do not like the way properties are declared in C# (I prefer the more visual tree syntax of XAML). Is there some way to have one XAML inherit from another? or a method like LoadXaml() that I can call on each Xamarin.Forms.ContentPage I create to inherit from a StylePage?
Here is my style xaml page:
<?xml version="1.0" encoding="UTF-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="Demo.StylePage">
<!-- Shared Properties -->
<ContentPage.Resources>
<ResourceDictionary>
<!-- TitleBar Styles -->
<Style x:Key="TitleBarStyle" TargetType="StackLayout">
<Setter Property="BackgroundColor" Value="#5db3d6"/>
<Setter Property="Padding" Value="15,6"/>
<Setter Property="HeightRequest" Value="44"/>
</Style>
<Style x:Key="TitleBarHeaderStyle" TargetType="Label">
<Setter Property="TextColor" Value="White"/>
<Setter Property="VerticalOptions" Value="CenterAndExpand"/>
<!-- <Setter Property="FontSize" Value="18"/>-->
<Setter Property="HorizontalOptions" Value="FillAndExpand"/>
</Style>
<Style x:Key="EmptyFrameStyle" TargetType="Frame">
<Setter Property="HasShadow" Value="false"></Setter>
<Setter Property="BackgroundColor" Value="Transparent"></Setter>
<Setter Property="Padding" Value="0,0"></Setter>
</Style>
</ResourceDictionary>
</ContentPage.Resources>
</ContentPage>
How could I load this resource dictionary from another file? Thank you for your time, Sergei.
ContentPages support inheritance. You can always define one BasePage, implement your resources there, and then have each new ContentPage inherit it. While I've never done this with inheriting xaml, I have used to share analytics, logging, etc. in my BasePage's code-behind (as shown below).
I'd suggest trying a similar approach and just instantiating your resource dictionary in your BasePage.
BaseFormPage:
public class BasePage : ContentPage
{
public BasePage () : base () { }
protected override void OnAppearing ()
{
base.OnAppearing ();
AnalyticsApi.LogPageView ();
AnalyticsApi.LogEvent(Title + " Page Loaded");
}
}
ChildFormPage:
<?xml version="1.0" encoding="UTF-8"?>
<local:BasePage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:MyApp;assembly=MyApp"
x:Class="MyApp.LoginPage"
Title="{x:Static local:Strings.SignIn}"
BackgroundColor="{x:Static local:Colors.ThemeQuaternary}">
<StackLayout>
...
</StackLayout>
</local:BasePage>
You can replace your App.cs with a XAML/cs combo as shown here
The resources defined in your App.xaml will be available for every view loaded in your app.
Make sure your App.xaml file has a build action of "Embedded Resource". Alternatively you can add it as a ContentView with XAML from the UI and then replace ContentView with Application
App.xaml
<Application
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="WorkingWithAppResources.App">
<Application.Resources>
<ResourceDictionary>
<Style x:Key="labelStyle" TargetType="Label">
<Setter Property="TextColor" Value="Green" />
</Style>
</ResourceDictionary>
</Application.Resources>
</Application>
App.xaml.cs
public partial class App : Application
{
public App ()
{
InitializeComponent ();
MainPage = YourContentPage(); // change as required
}
}
In Xamarin.Forms, you can declare resources on every VisualElement. You then access those resources using either {StaticResource} or {DynamicResource}.
The resolution rules applied are roughly as follows:
for {StaticResource}:
Look in this VisualElement.Resources or any of its parent in the same XAML file
Then look in Application.Current.Resources
for {DynamicResource}:
Look in this VisualElement.Resources or any of its parent, even the ones not defined in the same XAML file, and up to the Application.Resources
note that {DynamicResources} supports adding resources later, or changing parents
To answer your question, you can indeed define your Styles in a base class in XAML and use XAML inheritance, or add all your resources to your Application class. If you don't have a XAML file for your Application, just add one, and call InitializeComponents() from the Application constructor.