Set Background image to a page/screen in Xamarin Forms - c#

I am trying to make an app, using Xamarin Forms, in Visual Studio 2015. I want to add background image to the screen/page. So far, I have reached here, as seen in the below code but it doesn't work.
This is my MainPage.XAML code.
<?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:local="clr-namespace:TrackMyMeds"
x:Class="TrackMyMeds.MainPage"
BackgroundImage="/Images/blue_gradient">
<StackLayout BackgroundColor="Gray" Padding="8,15,8,0">
<Label HorizontalTextAlignment="Center" Text="Welcome to TrackMyMeds" TextColor="White" FontSize="40" FontAttributes="Bold">
</Label>
<Label HorizontalTextAlignment="Center" Text="Let us take charge of your health" TextColor="Black" FontSize="18">
</Label>
<StackLayout Padding="0,40,0,15">
<Label Text="If you already have an account:" TextColor="Black">
</Label>
<Button Clicked="LoginPage_Clicked" Text="Log In Here!" BackgroundColor="#387ef5" TextColor="White" FontSize="18">
</Button>
</StackLayout>
<StackLayout Padding="0,15,0,0">
<Label Text="If you're new here then:" TextColor="Black">
</Label>
<Button Clicked="SignupPage_Clicked" Text="Sign Up Here!" BackgroundColor="#387ef5" TextColor="White" FontSize="18">
</Button>
</StackLayout>
</StackLayout>
</ContentPage>
This is my MainPage.xaml.cs code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
namespace TrackMyMeds
{
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
}
private void LoginPage_Clicked(object sender, EventArgs e)
{
App.Current.MainPage = new LoginPage();
}
private void SignupPage_Clicked(object sender, EventArgs e)
{
App.Current.MainPage = new SignupPage();
}
}
}

You need to add the image file name to MainPage.xaml file as following:
<?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:local="clr-namespace:BgImgTestApp"
x:Class="BgImgTestApp.MainPage"
BackgroundImage="mobilebg.png">
<Label Text="Welcome to Xamarin Forms!"
VerticalOptions="Center"
HorizontalOptions="Center" />
</ContentPage>
Add your image file to respective folders.
For Android: Resources --> Drawable folder,
For iOS: Resources folder,
For Windows & Windows Phone: Assets folder.
You need to do these three changes in MainPage.xaml file for setting Background for Windows Desktop App and Windows Phone App.
1.Remove "Form: WindowsPage", switch to "Page".
2.Add Image Source
MainPage.xaml
<Page
x:Class="BgImgTestApp.Windows.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:forms="using:Xamarin.Forms.Platform.WinRT"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:BgImgTestApp.Windows"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Image Source="Assets/mobilebg.png"/>
</Grid>
</Page>
3.comment this:
MainPage.xaml.cs
//LoadApplication(new .....App());
Find the working sample app here: https://github.com/abhiguptame/xamarinsamples/tree/master/BgImgTestApp
Note: You may put resized images according to your device and platform.

If you're viewing on Android you need to keep the file in the the drawable folder of the android project then simply
<ContentPage BackgroundImage = "image.jpg">... </ContentPage>

Got it Right, Just reduced image size and dragged and dropped to the specific folders in Android-->Resources-->drawable directory and iOS resources directory.
Thanks anyways.

Related

In Xamarin, How to use ContentView as UIView in IOS

I have a test page inherited from ContentView in Xamarin Forms.
I want to use it in IOS . But I have a conversion promlem (Can Not Convert from ContentView to UIView)
My test page is below.
<?xml version="1.0" encoding="utf-8" ?>
<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class=".....TestPage">
<ContentView.Content>
<StackLayout>
<Label x:Name="TestLabel"
Text="TEST PAGE OPENING"
VerticalOptions="CenterAndExpand"
HorizontalOptions="CenterAndExpand" />
</StackLayout>
</ContentView.Content>
</ContentView>
My IOS Function is below.
public override void ViewDidLoad()
{
TestPage page = new TestPage();
View.AddSubview(page);
base.ViewDidLoad();
}
Looking for your helps.
Thanks!

Xamarin.Forms Navigation.PushAsync as Side Menu

I am using Xamarin.Forms and I have 2 pages, one is a List View, the other is a just a view I am using as a filter for the List View. I am currently using Navigation.PushAsync to display this page, my question is, is there away to present it like a side menu? I know there is Master Detail View which I am already using for the main menu and I dont think I can have 2 Master Details in my app, I tried that approach but it adds an additional navigation.
Here is my code.
public partial class PatientsPage : ContentPage
{
public PatientsPage()
{
InitializeComponent();
ToolbarItems.Add(new ToolbarItem("Filter", "filter.png", () => { openFilter(); }));
}
public async void openFilter()
{
await Navigation.PushAsync(new PatientFiltersPage());
}
}
UPDATE
Is there away to have 2 details in 1 master to accomplish this? I really don't want to use a 3rd party library.
I personally do not know of
any way to have 2 details in 1 master
According to the documentation:
The Xamarin.Forms MasterDetailPage is a page that manages two related pages of information – a master page that presents items, and a detail page that presents details about items on the master page.
So in theory only one Detail page is allowed per Master page (although the detail page can be a NavigationPage itself).
But if you are flexible about how to approach your problem, i would suggest using an overlay with AbsoluteLayout.
As an example, look at the image below, where i have a view over the main CollectionView that can be shown or hidden by tapping on the "Filter" button:
Of course you can get as creative as you want, and make the view appear sliding from below, or from the side, or fading in: there is a robust support for animations in Xamarin.Forms. Also the view can be scrollable so that if you have a variety of filters you do not cover the whole CollectionView with the Filter.
If that kind of solution is tolerable, you can achieve it as follows:
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="FilterDetail.StartPage">
<ContentPage.ToolbarItems>
<ToolbarItem Text="Filter"
Clicked="ToolbarItem_Clicked"/>
</ContentPage.ToolbarItems>
<ContentPage.Content>
<AbsoluteLayout>
<CollectionView x:Name="listView" AbsoluteLayout.LayoutBounds="0,0,1,1"
AbsoluteLayout.LayoutFlags="All">
<CollectionView.ItemTemplate>
<DataTemplate>
<StackLayout>
<Frame Margin="15">
<Label Text="{Binding .}"/>
</Frame>
</StackLayout>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
<ContentView x:Name="FilterOverlay"
IsVisible="True" VerticalOptions="End"
AbsoluteLayout.LayoutBounds="0,0,1,1"
AbsoluteLayout.LayoutFlags="All"
BackgroundColor="Transparent">
<Frame CornerRadius="10"
Margin="10"
HorizontalOptions="FillAndExpand" InputTransparent="False">
<StackLayout Padding="0">
<Label x:Name="FilterText"
Text="Filter Options"
FontSize="Medium"
TextColor="Black"/>
<StackLayout Orientation="Horizontal"
HorizontalOptions="CenterAndExpand">
<Label Text="Filter key 1"/>
<Switch IsToggled="True" />
</StackLayout>
<StackLayout Orientation="Horizontal"
HorizontalOptions="CenterAndExpand">
<Label Text="Filter key 2"/>
<Switch IsToggled="True" />
</StackLayout>
<StackLayout Orientation="Horizontal"
HorizontalOptions="CenterAndExpand">
<Label Text="Filter key 3"/>
<Switch IsToggled="False" />
</StackLayout>
<StackLayout Orientation="Horizontal"
HorizontalOptions="CenterAndExpand">
<Label Text="Filter key 4"/>
<Switch IsToggled="True" />
</StackLayout>
<Button Text="Apply"
HeightRequest="30"
Padding="0"
BackgroundColor="Accent"/>
</StackLayout>
</Frame>
</ContentView>
</AbsoluteLayout>
</ContentPage.Content>
</ContentPage>
Code behind
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace FilterDetail
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class StartPage : ContentPage
{
public StartPage()
{
InitializeComponent();
var items = new List<String>();
for (int i = 0; i < 1000; i++)
items.Add($"Item {i}");
listView.SetBinding(CollectionView.ItemsSourceProperty, new Binding() { Source = items, Path = "." });
}
private void ToolbarItem_Clicked(object sender, EventArgs e)
{
FilterOverlay.IsVisible = !FilterOverlay.IsVisible;
}
}
}
Update
In order to simulate a second Master/Menu we can simply modify our solution presented above in order to expand our overlay vertically and add some animation so that instead of simply appear and disappear, the overlay hides to the right.
Let's see how this is done:
The Overlay
Add an overlay that covers the whole screen except from a margin on the left so that it looks like a Master Menu.
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="FilterDetail.StartPage">
<ContentPage.ToolbarItems>
<ToolbarItem Text="Filter"
Clicked="ToolbarItem_Clicked"/>
</ContentPage.ToolbarItems>
<ContentPage.Content>
<AbsoluteLayout>
<CollectionView x:Name="listView" AbsoluteLayout.LayoutBounds="0,0,1,1"
AbsoluteLayout.LayoutFlags="All">
<CollectionView.ItemTemplate>
<DataTemplate>
<StackLayout>
<Frame Margin="15">
<Label Text="{Binding .}"/>
</Frame>
</StackLayout>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
<ContentView x:Name="FilterOverlay"
IsVisible="True"
AbsoluteLayout.LayoutBounds="0,0,1,1"
AbsoluteLayout.LayoutFlags="All"
BackgroundColor="Transparent">
<Frame CornerRadius="10"
Margin="100,10,0,10"
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand"
InputTransparent="False">
<StackLayout Padding="0">
<Label x:Name="FilterText"
Text="Filter Options"
FontSize="Medium"
TextColor="Black"/>
<StackLayout Orientation="Horizontal"
HorizontalOptions="CenterAndExpand">
<Label Text="Filter key 1"/>
<Switch IsToggled="True" />
</StackLayout>
<StackLayout Orientation="Horizontal"
HorizontalOptions="CenterAndExpand">
<Label Text="Filter key 2"/>
<Switch IsToggled="True" />
</StackLayout>
<StackLayout Orientation="Horizontal"
HorizontalOptions="CenterAndExpand">
<Label Text="Filter key 3"/>
<Switch IsToggled="False" />
</StackLayout>
<StackLayout Orientation="Horizontal"
HorizontalOptions="CenterAndExpand">
<Label Text="Filter key 4"/>
<Switch IsToggled="True" />
</StackLayout>
<Button Text="Apply"
HeightRequest="30"
Padding="0"
BackgroundColor="Accent"
VerticalOptions="EndAndExpand"/>
</StackLayout>
</Frame>
</ContentView>
</AbsoluteLayout>
</ContentPage.Content>
</ContentPage>
Next, add some animation to ToolbarItem_Clicked so that on tapping the Filter toolbar item, the overlay
hides to the right
Code Behind:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace FilterDetail
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class StartPage : ContentPage
{
public StartPage()
{
InitializeComponent();
var items = new List<String>();
for (int i = 0; i < 1000; i++)
items.Add($"Item {i}");
listView.SetBinding(CollectionView.ItemsSourceProperty, new Binding() { Source = items, Path = "." });
}
private async void ToolbarItem_Clicked(object sender, EventArgs e)
{
if (FilterOverlay.IsVisible)
{
// If overlay is visible, slide it to the right, and set as invisible.
await FilterOverlay.TranslateTo(this.Width-100, FilterOverlay.Y);
FilterOverlay.IsVisible = false;
}
else
{
// If overlay is invisible, make it visible and slide to the left.
FilterOverlay.IsVisible = true;
await FilterOverlay.TranslateTo(0, FilterOverlay.Y);
}
}
}
}
And that's it. The result looks like this:
Of course this is only a sample, and a bit of extra work on the overlay and on the animation can give you amazing results. Enjoy!

How can I add a Webview below a label or image and scroll all elements together for both IOS and Android?

Im developing a Xamarin.Forms application for both IOS and Android. My code in the XAML file is like this:
<StackLayout BackgroundColor="White" Padding="1" VerticalOptions="FillAndExpand">
<Image HeightRequest="150" Aspect="AspectFill" Source="{Binding Post.ImageUrl}" />
<Label Text="{Binding Post.Title}" VerticalOptions="FillAndExpand" FontFamily="{StaticResource BoldFont}" FontSize="20" />
<Label Text="{Binding Post.CreatedOn}" VerticalOptions="FillAndExpand" FontFamily="{StaticResource NormalFont}" FontSize="12" />
<WebView x:Name="WebViewer" HeightRequest="500" VerticalOptions="FillAndExpand" BackgroundColor="White">
<WebView.Source>
<HtmlWebViewSource Html="{Binding Post.Data.Content}" />
</WebView.Source>
</WebView>
<Label Text="Comments" FontSize="12" />
</StackLayout>
When I simulate the application, only the Webview Scrolls and all the other elements stay fixed in place. Theres another similar question on Stackoverflow, but the solution doesn't work and it doesnt answer my question for IOS, it is only targetted for Android.
This image shows the webview scrolling, and it's siblings staying in place
I would like that they all scroll together so that it acts like one page. This should be a crossplatform solution, so I only have to write the code once for both IOS and Android. How can I achieve this?
You can try something like that
Design Side
<?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="XamarinTest.View.WebViewDemo">
<ContentPage.Content>
<ScrollView>
<StackLayout BackgroundColor="White" Padding="1" VerticalOptions="FillAndExpand">
<Image HeightRequest="150" Aspect="AspectFill" Source="home" />
<Label Text="Header" FontSize="20" />
<Label Text="Subheader" FontSize="12" />
<WebView Source="http://www.google.com" x:Name="WebViewer" BackgroundColor="White">
</WebView>
<Label Text="Comments" FontSize="12" />
</StackLayout>
</ScrollView>
</ContentPage.Content>
</ContentPage>
Coding Side
using System;
using System.Collections.Generic;
using Xamarin.Forms;
namespace XamarinTest.View
{
public partial class WebViewDemo : ContentPage
{
public WebViewDemo()
{
InitializeComponent();
}
protected override void OnAppearing()
{
base.OnAppearing();
}
protected override void OnSizeAllocated(double width, double height)
{
base.OnSizeAllocated(width, height);
WebViewer.HeightRequest = height;
WebViewer.WidthRequest = width;
}
}
}

ControlTemplate overrides controls added programmatically

I Am trying to create a dummy app that has multiple "Branding Packages".
I have read that using a control template is the easiest way to apply a global styling to the app. most controls in the app will be added dynamically via the code behind.
However whenever I set the content view to use the control template none of the controls I have added via code will display
Here is the 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"
x:Class="TestWebApp.App">
<Application.Resources>
<ResourceDictionary>
<ControlTemplate x:Key="Template">
<Grid>
<Label Text="Control Template Demo App"
TextColor="White">
</Label>
<ContentPresenter/>
<BoxView Color="Teal" />
<Label Text="(c) WTF 2018"
TextColor="White"
VerticalOptions="Center"/>
</Grid>
</ControlTemplate>
</ResourceDictionary>
</Application.Resources>
</Application>
Here is the MainPage.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:local="clr-namespace:TestWebApp"
x:Class="TestWebApp.MainPage">
<ContentView ControlTemplate="{StaticResource Template}">
<ScrollView>
<StackLayout Orientation="Vertical" x:Name="MenuLayout">
</StackLayout>
</ScrollView>
</ContentView>
</ContentPage>
And here is the MainPage.xaml.cs
using System;
using System.Collections.Generic;
using Xamarin.Forms;
namespace TestWebApp
{
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
List<Object> testList = TestMethod();
foreach(Object testObject in testList)
{
MenuLayout.Children.Add((View)testObject);
}
}
public List<Object> TestMethod()
{
Button newButton = new Button {Text = "This is a Test Button", BackgroundColor = Color.White};
List<Object> returnList = new List<object>();
returnList.Add(newButton);
return returnList;
}
}
}
Is there a way to dynamically create a page from the code behind while still implementing the control template
Try to add some RowDefinitions to the Grid in the template:
<ControlTemplate x:Key="Template">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Label Text="Control Template Demo App" TextColor="White" />
<ContentPresenter Grid.Row="1" />
<BoxView Color="Teal" Grid.Row="2" />
<Label Text="(c) WTF 2018" TextColor="White" VerticalOptions="Center" Grid.Row="3"/>
</Grid>
</ControlTemplate>

Xamarin base ContentPage with loading (or common ContentViews)

how can I create a "base" ContentPage that contains, for sample, a busy indicator, and make this Page the base for each other pages inside my application?
I have tried to do in this way, but the busy indicator isn't showed.
Base 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"
xmlns:core="clr-namespace:SgatMobileV3.Core;assembly=SgatMobileV3"
x:Class="SgatMobileV3.Core.BasePage">
<ContentPage.Content>
<Grid>
<core:VolosLoadingView />
</Grid>
</ContentPage.Content>
</ContentPage>
Busy indicator view:
<?xml version="1.0" encoding="UTF-8"?>
<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:core="clr-namespace:SgatMobileV3.Core;assembly=SgatMobileV3"
core:LocatorViewModel.AutoWireViewModel="true"
x:Class="SgatMobileV3.Core.VolosLoadingView"
xmlns:busyindicator="clr-namespace:Syncfusion.SfBusyIndicator.XForms;assembly=Syncfusion.SfBusyIndicator.XForms">
<Grid>
<Grid BackgroundColor="LightGray" Opacity="0.6" IsVisible="True" />
<busyindicator:SfBusyIndicator
IsBusy="True"
IsVisible="True"
x:Name="loading" AnimationType="DoubleCircle"
ViewBoxWidth="150" ViewBoxHeight="150"
TextColor="Green" BackgroundColor="Transparent"
HorizontalOptions="Center" VerticalOptions="Center"/>
</Grid>
</ContentView>
A page:
<core:BasePage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:core="clr-namespace:SgatMobileV3.Core;assembly=SgatMobileV3"
core:LocatorViewModel.AutoWireViewModel="true"
x:Class="SgatMobileV3.Views.MockPage">
<ContentPage.Content>
<Grid>
<Button Text="Welcome to Xamarin.Forms! 1"
VerticalOptions="CenterAndExpand"
HorizontalOptions="CenterAndExpand"
Command="{Binding Test_ClickCommand}" />
</Grid>
</ContentPage.Content>
</core:BasePage>
I have tried to include a sample label inside the base page but nothing appears.
how can I create a "base" ContentPage that contains, for sample, a busy indicator, and make this Page the base for each other pages
If want Creating a ControlTemplate at Page Level,creating ControlTemplate instances at the application level, they can also be created at the page level, as shown in the following code example:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="SimpleTheme.HomePage">
<ContentPage.Resources>
<ResourceDictionary>
<ControlTemplate x:Key="TealTemplate">
...
</ControlTemplate>
<ControlTemplate x:Key="AquaTemplate">
...
</ControlTemplate>
</ResourceDictionary>
</ContentPage.Resources>
<ContentView ... ControlTemplate="{StaticResource TealTemplate}">
...
</ContentView>
</ContentPage>
When adding a ControlTemplate at the page level, a ResourceDictionary is added to the ContentPage, and then theControlTemplate` instances are included in the ResourceDictionary.
And also can use code , from doc has a sample for example.
You can do that adding the control in the code (in BasePage.cs file), I don't think there is XAML solution for that.

Categories