I'm using the AnimationNavigationPage nuget package (found here) to try and create a page slide animation going from right to left. So far it seems that all I'm able to get is left to right and it doesn't reflect when I change the animation type / subtype.
I'm sure I'm just missing something small but for the life of me I can't see it.
MainPage.xaml.cs
using FormsControls.Base;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
namespace PageNavigationExample
{
// Learn more about making custom code visible in the Xamarin.Forms previewer
// by visiting https://aka.ms/xamarinforms-previewer
[DesignTimeVisible(false)]
public partial class MainPage : AnimationPage
{
public MainPage()
{
InitializeComponent();
}
private async void Button_Clicked(object sender, EventArgs e)
{
await Navigation.PushAsync(new Page1());
}
}
}
MainPage.xaml
<?xml version="1.0" encoding="utf-8" ?>
<controls:AnimationPage
xmlns:controls="clr-namespace:FormsControls.Base;assembly=FormsControls.Base" xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
x:Class="PageNavigationExample.MainPage">
<controls:AnimationPage.PageAnimation>
<controls:SlidePageAnimation Duration="Short" Type="Slide" Subtype="FromRight"/>
</controls:AnimationPage.PageAnimation>
<StackLayout>
<!-- Place new controls here -->
<Label Text="Main page"
HorizontalOptions="Center"
VerticalOptions="CenterAndExpand" />
<Button Text="Main page button"
Clicked="Button_Clicked"/>
</StackLayout>
</controls:AnimationPage>
And then just basic content pages for navigation purposes that I haven't modified...Page1, Page2, etc.
What am I missing here to just get the slide animation to slide in from the right when I click a button and slide in from the left when I click the Back button?
And then just basic content pages for navigation purposes that I
haven't modified...Page1, Page2, etc.
Have you let your Page1, Page2, etc to inherit AnimationPage and set the PageAnimation?
for example:
app.xaml.cs :
public App()
{
InitializeComponent();
MainPage = new AnimationNavigationPage(new MainPage());
}
MainPage.xaml.cs:
public partial class MainPage : AnimationPage
{
public MainPage()
{
InitializeComponent();
}
private async void Button_Clicked(object sender, EventArgs e)
{
await Navigation.PushAsync(new Page1());
}
}
MainPage.xaml:
<?xml version="1.0" encoding="utf-8" ?>
<controls:AnimationPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
xmlns:controls="clr-namespace:FormsControls.Base;assembly=FormsControls.Base"
x:Class="App18.MainPage">
<controls:AnimationPage.PageAnimation>
<controls:SlidePageAnimation Duration="Medium" Subtype="FromRight" />
</controls:AnimationPage.PageAnimation>
<StackLayout>
<!-- Place new controls here -->
<Label Text="Main page"
HorizontalOptions="Center"
VerticalOptions="CenterAndExpand" />
<Button Text="Main page button"
Clicked="Button_Clicked"/>
</StackLayout>
</controls:AnimationPage>
Page1.xaml.cs:
public partial class Page1: AnimationPage
{
public Anim2()
{
InitializeComponent();
}
}
Page1.xaml:
<?xml version="1.0" encoding="utf-8" ?>
<controls:AnimationPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
xmlns:controls="clr-namespace:FormsControls.Base;assembly=FormsControls.Base"
x:Class="App18.Page1">
<controls:AnimationPage.PageAnimation>
<controls:SlidePageAnimation Duration="Short" Type="Slide" Subtype="FromRight"/>
</controls:AnimationPage.PageAnimation>
<StackLayout>
<Label Text="Welcome to Xamarin.Forms!"
VerticalOptions="CenterAndExpand"
HorizontalOptions="CenterAndExpand" />
</StackLayout>
</controls:AnimationPage>
the effect like:
Related
I am trying to create bottom tabbed page in Xamarin forms and i am doing this for Android.
here i am using latest version of Xamarin Forms.
My sample Bottom tabbed page like below.
<TabbedPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:views="clr-namespace:SampleTabbedPage.Views"
xmlns:android="clr-namespace:Xamarin.Forms.PlatformConfiguration.AndroidSpecific;assembly=Xamarin.Forms.Core"
android:TabbedPage.ToolbarPlacement="Bottom"
android:TabbedPage.BarItemColor="Gray"
android:TabbedPage.BarSelectedItemColor="Blue"
mc:Ignorable="d"
x:Class="SampleTabbedPage.Views.SampleTabbed">
<!--Pages can be added as references or inline-->
<NavigationPage
Title="Main"
NavigationPage.HasNavigationBar="False">
<x:Arguments>
<views:SampleDetailsPage/>
</x:Arguments>
</NavigationPage>
<ContentPage Title="Tab 1" />
<ContentPage Title="Tab 2" />
</TabbedPage>
My sample details page like
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
x:Class="SampleTabbedPage.Views.SampleDetailsPage"
BackgroundColor="Gray">
<ContentPage.Content>
<StackLayout>
<ListView BackgroundColor="White" ItemTapped="ListView_ItemTapped">
<ListView.ItemsSource>
<x:Array Type="{x:Type x:String}">
<x:String>Mango</x:String>
<x:String>Banana</x:String>
<x:String>Pinaple</x:String>
<x:String>Apple</x:String>
<x:String>Avacado</x:String>
<x:String>Coconut</x:String>
<x:String>Dragan Fruit</x:String>
<x:String>Pomaganate</x:String>
<x:String>Wood Apple</x:String>
</x:Array>
</ListView.ItemsSource>
</ListView>
</StackLayout>
</ContentPage.Content>
</ContentPage>
And the navigation i am doing as follows
in App.xamal.cs
MainPage = new NavigationPage(new FirstPage());
I have simple first page
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
x:Class="SampleTabbedPage.Views.FirstPage">
<ContentPage.Content>
<StackLayout>
<Button Text="Click Me!" Clicked="Button_Clicked"
VerticalOptions="CenterAndExpand"
HorizontalOptions="CenterAndExpand" />
</StackLayout>
</ContentPage.Content>
</ContentPage>
here in button click event i do the navigation to "Sample Tabbed Page"
await Navigation.PushAsync(new SampleTabbed());
This is working fine.
but there is a performance issue.
if i run this and click on button in First page it is taking 3 seconds to load tabbed page.
if i remove list view in sample detail page it take 2 seconds to load.
but if i add just a content page to click event it take only milliseconds to load.
Am i doing some thing wrong with implementing tabbed page?
or
is there any way to improve the loading performance with tabbed pages.
A solution is to make the heavy pages load their content in a lazy manner, only when their tab becomes selected. This way, since these pages are now empty when TabbedPage is created, navigating to the TabbedPage suddenly becomes very fast!
1.create a behavior for the TabbedPage page, called ActivePageTabbedPageBehavior.
class ActivePageTabbedPageBehavior : Behavior<TabbedPage>
{
protected override void OnAttachedTo(TabbedPage tabbedPage)
{
base.OnAttachedTo(tabbedPage);
tabbedPage.CurrentPageChanged += OnTabbedPageCurrentPageChanged;
}
protected override void OnDetachingFrom(TabbedPage tabbedPage)
{
base.OnDetachingFrom(tabbedPage);
tabbedPage.CurrentPageChanged -= OnTabbedPageCurrentPageChanged;
}
private void OnTabbedPageCurrentPageChanged(object sender, EventArgs e)
{
var tabbedPage = (TabbedPage)sender;
// Deactivate previously selected page
IActiveAware prevActiveAwarePage = tabbedPage.Children.OfType<IActiveAware>()
.FirstOrDefault(c => c.IsActive && tabbedPage.CurrentPage != c);
if (prevActiveAwarePage != null)
{
prevActiveAwarePage.IsActive = false;
}
// Activate selected page
if (tabbedPage.CurrentPage is IActiveAware activeAwarePage)
{
activeAwarePage.IsActive = true;
}
}
}
2.define IActiveAware interface
interface IActiveAware
{
bool IsActive { get; set; }
event EventHandler IsActiveChanged;
}
3.create a base generic abstract class called LoadContentOnActivateBehavior
abstract class LoadContentOnActivateBehavior<TActivateAwareElement> : Behavior<TActivateAwareElement>
where TActivateAwareElement : VisualElement
{
public DataTemplate ContentTemplate { get; set; }
protected override void OnAttachedTo(TActivateAwareElement element)
{
base.OnAttachedTo(element);
(element as IActiveAware).IsActiveChanged += OnIsActiveChanged;
}
protected override void OnDetachingFrom(TActivateAwareElement element)
{
(element as IActiveAware).IsActiveChanged -= OnIsActiveChanged;
base.OnDetachingFrom(element);
}
void OnIsActiveChanged(object sender, EventArgs e)
{
var element = (TActivateAwareElement)sender;
element.Behaviors.Remove(this);
SetContent(element, (View)ContentTemplate.CreateContent());
}
protected abstract void SetContent(TActivateAwareElement element, View contentView);
}
4.the specialized LazyContentPageBehavior
class LazyContentPageBehavior : LoadContentOnActivateBehavior<ContentView>
{
protected override void SetContent(ContentView element, View contentView)
{
element.Content = contentView;
}
}
then we can use in xaml like this:
<TabbedPage>
<TabbedPage.Behaviors>
<local:ActivePageTabbedPageBehavior />
</TabbedPage.Behaviors>
<ContentPage Title="First tab">
<Label Text="First tab layout" />
</ContentPage>
<local:LazyLoadedContentPage Title="Second tab">
<ContentPage.Behaviors>
<local:LazyContentPageBehavior ContentTemplate="{StaticResource ContentTemplate}" />
</ContentPage.Behaviors>
<ContentPage.Resources>
<ResourceDictionary>
<DataTemplate x:Key="ContentTemplate">
<!-- Complex and slow to render layout -->
<local:SlowContentView />
</DataTemplate>
</ResourceDictionary>
</ContentPage.Resources>
</local:LazyLoadedContentPage>
</TabbedPage>
we moved the ContentPage complex layout to become a DataTemplate.
Here's the custom LazyLoadedContentPage page which is activation aware:
class LazyLoadedContentPage : ContentPage, IActiveAware
{
public event EventHandler IsActiveChanged;
bool _isActive;
public bool IsActive
{
get => _isActive;
set
{
if (_isActive != value)
{
_isActive = value;
IsActiveChanged?.Invoke(this, EventArgs.Empty);
}
}
}
}
SlowContentView do some complex things
public partial class SlowContentView : ContentView
{
public SlowContentView()
{
InitializeComponent();
// Simulating a complex view
...
}
}
In Xamarin.Forms I would like to bind a code behind property to a label in XAML.
I found many answers and web pages about this topic, but they all cover more complex scenarios.
This is my 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"
xmlns:local="clr-namespace:TrackValigie"
x:Class="TrackValigie.SelViaggioPage">
<ContentPage.Content>
<StackLayout>
<Label Text="{Binding ?????????}" />
</StackLayout>
</ContentPage.Content>
</ContentPage>
And this is code behind:
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class SelViaggioPage : ContentPage
{
private string _lblText;
public string LblText
{
get
{
return _lblText;
}
set
{
_lblText = value;
OnPropertyChanged();
}
}
public SelViaggioPage()
{
InitializeComponent();
}
protected override void OnAppearing()
{
this.LblText = "Ciao!!";
base.OnAppearing();
}
}
I would like to bind the "LblText" property to the label, using XAML only, that means without setting binding or binding context in code behind.
Is this possible?
your page will need to implement INotifyPropertyChanged, but the binding syntax should just be
<ContentPage x:Name="MyPage" ... />
...
<Label BindingContext="{x:Reference Name=MyPage}" Text="{Binding LblText}" />
Or if you don't want to swap the binding context for the entire control then use the 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"
x:Name="this"
x:Class="SomePage">
<ContentPage.Content>
<StackLayout>
<Label Text="{Binding SomeProp, Source={x:Reference this}}" />
</StackLayout>
</ContentPage.Content>
</ContentPage>
Just add BindingContext = this; in code behind file.
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:TrackValigie"
x:Class="TrackValigie.SelViaggioPage">
<ContentPage.Content>
<StackLayout>
<Label Text="{Binding LblText}" />
</StackLayout>
</ContentPage.Content>
</ContentPage>
Code Behind
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class SelViaggioPage : ContentPage
{
private string _lblText;
public string LblText
{
get
{
return _lblText;
}
set
{
_lblText = value;
OnPropertyChanged();
}
}
public SelViaggioPage()
{
InitializeComponent();
BindingContext = this;
}
protected override void OnAppearing()
{
base.OnAppearing();
this.LblText = "Ciao!!";
}
}
You need to set the x:Name for ContentPage as mentioned by Jason's Answer .
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:TrackValigie"
x:Class="TrackValigie.SelViaggioPage"
x:Name = "MyControl"/>
Instead of using BindingContext, you can use ElementName
<TextBlock Text="{Binding ElementName=TestControl,Path=StudentName}"/>
Hello I am working on a xamarin forms app the displays a map and when the user clicks a button the maps legend image pops up on top of the map. I am using this nuget package to get the popup effect: Rtorgames Popup package
the issue is that when I click the button the popup works but no legend image is showing up and the images are in the correct directories for both iOS and android.
heres my xaml code for the MapPage.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="AppName.Forms.Pages.Map">
<ContentView x:Name="contentView" ControlTemplate="{StaticResource MapNavBar}">
<StackLayout>
<Button Text = "Legand" HorizontalOptions = "End" VerticalOptions="End" Clicked="legend_OnClicked"></Button>
<Grid HorizontalOptions="FillAndExpand" >
<Image Source="Map.png" Scale="1.0" Aspect="AspectFit" />
</Grid>
</StackLayout>
</ContentView>
</ContentPage>
here's the code behind for MapPage.xaml:
using System;
using Rg.Plugins.Popup.Extensions;
using Rg.Plugins.Popup.Services;
using Xamarin.Forms;
namespace AppName.Forms.Pages
{
public partial class Map : ContentPage
{
public Map()
{
InitializeComponent();
}
private async void legend_OnClicked(object sender, EventArgs e)
{
var page = new LegendPage();
await Navigation.PushPopupAsync(page);
}
}
}
here's the legendPage xaml code:
<?xml version="1.0" encoding="utf-8" ?>
<pages:PopupPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:pages="clr-namespace:Rg.Plugins.Popup.Pages;assembly=Rg.Plugins.Popup"
xmlns:animations="clr-namespace:Rg.Plugins.Popup.Animations;assembly=Rg.Plugins.Popup"
x:Class="AppName.Forms.Pages.LegendPage">
<StackLayout>
<Grid HorizontalOptions="FillAndExpand" >
<Image Source="legend.png" Scale="1.0" Aspect="AspectFit" />
</Grid>
</StackLayout>
</pages:PopupPage>
and finally here's the code behind to the legendPage.xaml:
using Xamarin.Forms;
using System;
using Rg.Plugins.Popup.Pages;
using System.Threading.Tasks;
namespace AppName.Forms.Pages
{
public partial class LegendPage : PopupPage
{
public LegendPage()
{
}
protected override void OnAppearing()
{
base.OnAppearing();
}
protected override void OnDisappearing()
{
base.OnDisappearing();
}
// Method for animation child in PopupPage
// Invoced after custom animation end
protected override bool OnBackButtonPressed()
{
// Prevent hide popup
//return base.OnBackButtonPressed();
return true;
}
// Invoced when background is clicked
protected override bool OnBackgroundClicked()
{
// Return default value - CloseWhenBackgroundIsClicked
return base.OnBackgroundClicked();
}
}
}
any help would be amazing!
Thanks in advance! :)
I have a problem when trying to load the Icon of a ToolbarItem in Xamarin: It doesn't show up. The toolbar certainly exists. I have handled the Click method and it works, but the Icon is not visible. the ".ico" file exists in all the "drawable" folders in the Android project. It's the same .ico file I use in another solution and there it works just fine as the icon of a ToolbarItem, but here it doesn't work. I have tried to load an embedded image, but it doesn't work either. If I set its Text property, it is shown properly. I have a HomePage which is a MasterDetailPage, and the detail of this page is RootPage. On RootPage I have the ToolbarItem. Here are my xaml codes and the code behind:
HomePage:
<?xml version="1.0" encoding="utf-8" ?>
<MasterDetailPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:views="clr-namespace:ITEC.Views;assembly=ITEC"
x:Class="ITEC.Views.HomePage"
IsPresented="True">
<MasterDetailPage.Master>
<ContentPage Title="Home" Padding="0,20,0,0">
<StackLayout>
<ListView x:Name="listView">
<ListView.ItemTemplate>
<DataTemplate>
<TextCell Text="{Binding Title}"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage>
</MasterDetailPage.Master>
<MasterDetailPage.Detail>
<views:RootPage/>
</MasterDetailPage.Detail>
</MasterDetailPage>
Code behind:
using ITEC.Services;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace ITEC.Views
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class HomePage : MasterDetailPage
{
private OptionService _optionService;
public HomePage()
{
InitializeComponent();
Detail=new NavigationPage(new RootPage());
_optionService = new OptionService();
listView.ItemsSource = _optionService.GetOptions();
}
}
}
RootPage:
<?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:embedded="clr-namespace:ITEC.MarkupExtensions"
x:Class="ITEC.Views.RootPage">
<ContentPage.ToolbarItems>
<ToolbarItem Icon="settings.ico" Clicked="MenuItem_OnClicked"></ToolbarItem>
</ContentPage.ToolbarItems>
<StackLayout>
<Label>Hello world</Label>
</StackLayout>
</ContentPage>
Code behind:
using System;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace ITEC.Views
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class RootPage : ContentPage
{
public RootPage()
{
InitializeComponent();
}
private void MenuItem_OnClicked(object sender, EventArgs e)
{
DisplayAlert("Hello", "OK", "No");
}
}
}
Try png file for your icon. i think it might be work.
Im trying to add some items to a Listview which i added using Xamarin.Forms markup in an xaml file.
The button can be accessed by hooking with the click event.But since the listview is empty i need the event like ondraw like in winforms, so that i can hook to it when it is drawn.
In the XAML file I have :
<?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="ButtonXaml.ButtonXamlPage">
<StackLayout>
<Button Text="Tap for click count!"
BorderWidth="10"
TextColor="Red"
HorizontalOptions="Center"
Clicked="OnButtonClicked" />
<ListView
HorizontalOptions="Center"
/>
</StackLayout>
</ContentPage>
In the .cs file i have
using System;
using Xamarin.Forms;
namespace ButtonXaml
{
public partial class ButtonXamlPage
{
int count = 0;
public ButtonXamlPage()
{
InitializeComponent();
}
public void OnButtonClicked(object sender, EventArgs args)
{
((Button)sender).Text = "You clicked me";
}
}
}
So should i hook to events in Listview or can i do something like Resource.getElementbyID like we do in android
To access a Forms control in the code-behind, you need to assign it a name, using the x:Name attribute
in XAML:
<ListView HorizontalOptions="Center" x:Name="MyList" />
in code:
MyList.ItemsSource = myData;
There is a bug in Xamarin where VS doesn't see the defined x:Name
http://forums.xamarin.com/discussion/25409/problem-with-xaml-x-name-and-access-from-code-behind
Say you've defined an image in XAML:
<Image x:Name="myImageXName" />
Then this should work in code behind:
this.FindByName<Image>("myImageXName");
In my case the problem was lack of line XamlCompilation(XamlCompilationOptions.Compile)] in .xaml.cs file.
Example:
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
BindingContext = new MainPageViewModel();
}
...
}