Xamarin.Forms Navigation.PushAsync Not Working - c#

I have a Xamarin.Forms project, and I have a custom control that should open a new page when tapped. Unfortunately, nothing happens when I call Navigation.PushAsync(...);. I've read countless StackOverflow questions (such as this one) and Xamarin Forums threads and done several Google searches, but none of the solutions seem to solve my issue.
My control inherits from ContentView, as all Xamarin.Forms views
do.
src is a custom class that contains some data points that
are used by this control and EventDetailsPage.
I can confirm that the gesture does work itself, but the call to PushAsync() does nothing.
I have tried manipulating the statement in ways so that a NavigationPage is used (such that it becomes myNavigationPage.Navigation.PushAsync(new EventDetailsPage(src));).
I have also tried creating a constructor that takes a Page and uses it in away similar to the above point.
My control's constructor:
public EventControl() {
InitializeComponent();
GestureRecognizers.Add(new TapGestureRecognizer() {
Command = new Command(() => Navigation.PushAsync(new EventDetailsPage(src)))
});
}
Typically, asking a new question on StackOverflow is my last resort when nothing else that I've tried solved my problem. Any help is appreciated.

Change your App.cs like this
public App()
{
InitializeComponent();
MainPage = new NavigationPage(new MainPage());//Very important add this..
//MainPage = new MainPage(); //not like this
}

I found the problem. Keith Rome lead me to look through EventDetailsPage and I commented out a line of XAML, and that solved the problem. That line was adding a custom control to the page (not related to EventControl). I don't know if the control's definition or its custom render's definition was causing the strange behavior, but removing that line solved the issue.

Same problem for different reasons...
I got this problem, after installing updates in Visual Studio, including Xamarin.
After updating all my nuget packages, by the following (the first command to show which ones have updates), I was able to resolve the problem:
Get-Package -updates
Update-Package <package>
I suspect, removing the AppData\local\Xamarin folder (which seems to act as a cache) and letting it repopulate could also solve the problem.

I implemented AppShell class which has one input string, in order to set correct page:
public partial class AppShell : Shell
{
public AppShell(string startUpPageString = null)
{
InitializeComponent();
Page startUpPage;
if (startUpPageString == nameof(SignUpPage))
{
startUpPage = new SignUpPage();
}
else if (startUpPageString == nameof(LoginPinPage))
{
startUpPage = new LoginPinPage();
}
else
{
startUpPage = new SignUpPage();
}
ShellSection shellSection = new ShellSection();
shellSection.Items.Add(new ShellContent() { Content = startUpPage });
CurrentItem = shellSection;
RegisterRoutes();
}
private void RegisterRoutes()
{
...removed for clarity
}
}
among that, in my XAML I added some tabs (postlogin section) which are called though GoToAsync(postlogin) method:
<Shell xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:login="clr-namespace:XXX.Views.Login"
xmlns:postlogin ="clr-namespace:XXX.XXX.Views.PostLogin"
x:Class="XXX.AppShell"
FlyoutBehavior="Disabled">
<ShellItem Route="postlogin">
<ShellSection Route="activity_section" Title="Activity" Icon="Activity_Menu_Icon.png">
<ShellContent Route="page1"
Title="Page1"
Icon="Pag1.png"
ContentTemplate="{DataTemplate postlogin:Page1}" />
</ShellSection>
<ShellContent Route="page2"
Title="Page2"
Icon="Pag2.png"
ContentTemplate="{DataTemplate postlogin:Page2}" />
</ShellSection>
<ShellContent Route="page3"
Title="Page3"
Icon="Page3.png"
ContentTemplate="{DataTemplate postlogin:Page3}" />
</ShellSection>
<ShellContent Route="page4"
Title="Page4"
Icon="Pag4.png"
ContentTemplate="{DataTemplate postlogin:Page4}" />
</ShellSection>
</ShellItem>
<FlyoutItem Route="others"
Title="OTHERS"
FlyoutDisplayOptions="AsMultipleItems">
<Tab>
<ShellContent Route="cats"
Title="Cats"
Icon="next_7.png"
/>
<ShellContent Route="dogs"
Title="Dogs"
Icon="next_7.png"
/>
</Tab>
</FlyoutItem>
</Shell>
So, my problem is as follows: Once I got to for example, SignUpPage nad I click a button, and that button executes:
await Shell.Current.Navigation.PushAsync(new SentEmailPage()); it goews to catch part with an message: Object reference not set to an instance of an object.at Xamarin.Forms.ShellSection.OnPushAsync

this solved my problem
Device.InvokeOnMainThreadAsync(() =>
{
Navigation.PushAsync(new CameraPage());
});

Related

After making whole form disable, how to set one button to be enable?

I'm using WPF, and I have a form, on which there are many textboxes, buttons and whatnot.
For a specific reason I need that whole form to be disabled, which I managed with the code below -
public WPForm() //constructor
{
this.IsEnabled = false;
}
But, I have one button that sends me back to another form, which I need to be enabled (clickable), and what I have tried is simply setting it like this -
public WPForm() //constructor
{
this.IsEnabled = false;
btnBack.IsEnabled = true;
}
And this does basically nothing, so my question is, what else do I need to do in order to make it enabled?
Just dont set the whole Form to disabled.
Try to put a Grid or Stackpanel around the Controls that need to be disabled and disable them only. Maybe like so:
<Grid x:Name="myGrid">
//Your Controls
<Grid/>
<Button />
public WinForm() //constructor
{
myGrid.IsEnabled = false;
}

Automating Xamarin ToolbarItem click

I'm using Xamarin.UITest to write some automation.
The target app has this in its markup:
<ContentPage.ToolbarItems>
<ToolbarItem Icon="Settings" AutomationId="SettingsToolbarItem" Order="Primary" Priority="1" Command="{Binding ShowSettingsCommand}" />
</ContentPage.ToolbarItems>
So far I've had 3 approaches:
Using .Class and Indexing successfully finds the element
systemMenuButton = x => x.Class("android.support.v7.view.menu.ActionMenuItemView").Index(1);
Using .Property fails to find the element
systemMenuButton = e => e.Property("Command", "ShowSettingsCommand");
Similarly, using .Marked also fails to find the element
systemMenuButton = x => x.Marked("SettingsToolbarItem");
Relevant automation code is as follows:
using Query = System.Func<Xamarin.UITest.Queries.AppQuery, Xamarin.UITest.Queries.AppQuery>;
....
protected readonly Query systemMenuButton = x => x.Marked("SettingsToolbarItem");
....
app.Tap(systemMenuButton);
I get a generic "unable to find element" exception:
Unable to find element. Query for Marked("SettingsToolbarItem") gave no results.
I don't get this exception when clicking on other elements outside the ContentPage.ToolbarItems block on the same View/Page
I've hit the same problem - for some reason Android can't detect ToolbarItem.AutomationId.
A workaround is to assign ToolbarItem.Text the same value as ToolbarItem.AutomationId.
Xamarin.Forms.ContentPage
<ContentPage.ToolbarItems>
<ToolbarItem Icon="Settings" Text="SettingsToolbarItem" AutomationId="SettingsToolbarItem" Order="Primary" Priority="1" Command="{Binding ShowSettingsCommand}" />
</ContentPage.ToolbarItems>
Xamarin.UITest
using Query = System.Func<Xamarin.UITest.Queries.AppQuery, Xamarin.UITest.Queries.AppQuery>;
// ....
protected readonly Query systemMenuButton = x => x.Marked("SettingsToolbarItem");
//....
public void TapSystemMenuButton()
{
app.Tap(systemMenuButton);
app.Screenshot("Tapped System Menu Button");
}
Here's is a sample app where I use similar logic to tap a ToolbarItem in a UITest: https://github.com/brminnick/InvestmentDataSampleApp/
Edit
In the comments, you mentioned that you do not have access to the source code of the Xamarin.Forms app.
If you are unable to change the Xamarin.Forms source code, you will have to use x => x.Class("ActionMenuItemView").Index(1).
I don't recommend going this route because the int parameter of Index can vary depending on the device; it is not guaranteed to always be 1.
public void TapSystemMenuButton()
{
if (app is iOSApp)
app.Tap(systemMenuButton);
else
app.Tap(x => x.Class("ActionMenuItemView").Index(1));
app.Screenshot("Tapped System Menu Button");
}

Xamarin Forms Picker control opens when entering input in Entry control

For reproducing the problem, I have added 2 controls to a content page: Picker and Entry. The container is a TableView section.
If I click on the Entry control, causing the keyboard to open, or enter characters in it, the Picker selection is opening. It's opening every time I enter a character or removing one (so when the value is changing).
I don't have this problem if the main container isn't a TableView, but for example a StackLayout.
I have this problem since Xamarin Forms v3.3. In previous versions, like 3.2, this problem didn't exist. The problem also exists in the 3.4 beta.
Also: the problem only occurs in Android (version 4 - 9). Not in iOS.
Below you'll find my 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:PickerBugXF33"
x:Class="PickerBugXF33.MainPage">
<StackLayout>
<TableView x:Name="testTableView" Intent="Form" HasUnevenRows="true" />
</StackLayout>
</ContentPage>
Code behind:
using Xamarin.Forms;
namespace PickerBugXF33
{
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
testTableView.Root = new TableRoot();
var section = new TableSection("Test section");
testTableView.Root.Add(section);
var viewCell = new ViewCell();
section.Add(viewCell);
var stack = new StackLayout() { Orientation = StackOrientation.Vertical };
viewCell.View = stack;
var picker = new Picker();
picker.Items.Add("Test item in picker");
stack.Children.Add(picker);
var entry = new Entry();
stack.Children.Add(entry);
}
}
}
NB: This is a test project. The real live project is much larger in which the page has to be created via code.
Update 1, 11/9/2018: Might be solved by commit: https://github.com/xamarin/Xamarin.Forms/pull/4344/commits/8401d81745ad248b5b70aa669863c8b8c8753e66

ShieldUI will not accept updated attributes

I have the following code:
protected void SetChartToItem(Item item)
{
ShieldChart1 = new ShieldChart();
ShieldChart1.Width = Unit.Percentage(100);
ShieldChart1.Height = Unit.Pixel(400);
ShieldChart1.CssClass = "chart";
ShieldChart1.PrimaryHeader.Text = item.name;
ShieldChart1.TooltipSettings.AxisMarkers.Enabled = true;
ShieldChart1.TooltipSettings.AxisMarkers.Mode = ChartXYMode.XY;
ShieldChart1.TooltipSettings.AxisMarkers.Width = new Unit(1);
ShieldChart1.TooltipSettings.AxisMarkers.ZIndex = 3;
ChartAxisX axisX = new ChartAxisX();
axisX.Title.Text = "Times";
ShieldChart1.Axes.Add(axisX);
ChartAxisY axisY = new ChartAxisY();
axisY.Title.Text = "Prices";
ShieldChart1.Axes.Add(axisY);
ShieldChart1.Axes.SetDirty();
}
And the following code:
<shield:ShieldChart ID="ShieldChart1" Width="700px" Height="380px" runat="server" OnTakeDataSource="ShieldChart1_TakeDataSource" CssClass="chart">
<PrimaryHeader Text="TestHeader"></PrimaryHeader>
<ExportOptions AllowExportToImage="true" AllowPrint="false" />
<Axes>
<shield:ChartAxisX>
<Title Text="Time"></Title>
</shield:ChartAxisX>
<shield:ChartAxisY>
<Title Text="Price"></Title>
</shield:ChartAxisY>
</Axes>
<DataSeries>
<shield:ChartLineSeries DataFieldY="Volume" DataFieldX="Timer" CollectionAlias="Volume">
<Settings EnablePointSelection="true">
<PointMark>
<ActiveSettings>
<PointSelectedState DrawWidth="4" DrawRadius="4" />
</ActiveSettings>
</PointMark>
</Settings>
</shield:ChartLineSeries>
<shield:ChartLineSeries DataFieldY="Price" DataFieldX="Timer" CollectionAlias="Price">
<Settings EnablePointSelection="true">
<PointMark>
<ActiveSettings>
<PointSelectedState DrawWidth="4" DrawRadius="4" />
</ActiveSettings>
</PointMark>
</Settings>
</shield:ChartLineSeries>
</DataSeries>
</shield:ShieldChart>
When I call SetChartToItem, it looks like it works when I watch it go through step by step, but when the page renders there are no changes to the actual ShieldChart. More information that might help is when I remove the line ShieldChart1 = new ShieldChart(); then the entire ShieldChart will disappear instead.
I believe there are two ways to try and address this.
One would be to recreate the chart, as demonstrated in this sample:
https://demos.shieldui.com/aspnet/rangebar-chart/related-charts
You can check out the asp.net tab.
Another alternative would be to recreate the controls collection (and clear it before this) in a nested panel, which hosts the chart. Then, on a specific event, you can recreate the chart, clear the controls collection of the container and add the new instance.
It took me 3 months, but I figured out what the problem was. I was causing some of the chart to build itself in the 'Page_Load' function. The solution to this was to make sure everyone was done only if the page is a postback page, which is not included in my code above but fixed the issue for me.

Xamarin Forms Android: TabbedPage Font Style

how can I change the style of the tab title? The most important thing is, that the titles not cutted off like at the screenshot. So I have to change the size of the titles.
I started creating a Custom Renderer for tabbedpage, but I don't know how to go on.
Xaml:
<custom:CustomTabbedPage...
Forms:
public class CustomTabbedPage : TabbedPage...
Forms.Droid
public class CustomTabbedPageRenderer : TabbedPageRenderer
The TabbedPage has NavigationPages with ContentPages.
If you need further information, let me know. Thank you.
<TabbedPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:TabbedPageWithNavigationPage;assembly=TabbedPageWithNavigationPage"
x:Class="TabbedPageWithNavigationPage.MainPage">
<NavigationPage Title="Start" Icon="start.png">
<x:Arguments>
<local:StartPage />
</x:Arguments>
</NavigationPage>
<NavigationPage Title="Symptom-Tagebuch" Icon="tagebuch.png">
<x:Arguments>
<local:TagebuchPage />
</x:Arguments>
</NavigationPage>
...
It seems that the default title style of NavigationPage behaviors different on different size of device. By my side on 7" KitKat emulator it looks so:
and on 5" KitKat emulator it looks so:
Or it could be the version problem which cause the behavior of this NavigationPage by my side so different from yours, I can't reproduce yout issue. Anyway, if you want to customize the layout of your NavigationPage, you can create a custom render for your android platform. For more information, you can refer to the official document Customizing Controls on Each Platform, and if you're looking for a demo, there are discussions on the official forum about customize the title font of NavigationPage you may also take a look: Discussion 1 and Discussion 2.
Another possible solution to your problem is that I think you can change the NavigationPage to ContentPage, and change your sub pages to content view, and by doing this, you can refer to Xamarin.Forms: Can I embed one ContentPage or ContentView into another ContentPage.
According to your description, maybe the first solution by creating your own custom render is more suitable for your scenario.
You can find the textview of title through TabLayout view children in CustomRendered and change font style
[assembly: ExportRenderer(typeof(MainPage), typeof(BottomTabbedPageRenderer))]
namespace Daddy.Droid
{
public class BottomTabbedPageRenderer : TabbedPageRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<TabbedPage> e)
{
base.OnElementChanged(e);
if (e.NewElement == null || e.OldElement != null)
return;
TabLayout tablayout = (TabLayout)ViewGroup.GetChildAt(1);
Android.Views.ViewGroup vgroup = (Android.Views.ViewGroup)tablayout.GetChildAt(0);
for (int i = 0; i < vgroup.ChildCount; i++)
{
Android.Views.ViewGroup vvgroup = (Android.Views.ViewGroup)vgroup.GetChildAt(i);
Typeface fontFace = Typeface.CreateFromAsset(this.Context.Assets, "IranSans.ttf");
for (int j = 0; j < vvgroup.ChildCount; j++)
{
Android.Views.View vView = (Android.Views.View)vvgroup.GetChildAt(j);
if (vView.GetType() == typeof(Android.Support.V7.Widget.AppCompatTextView) || vView.GetType() == typeof(Android.Widget.TextView))
{
//here change textview style
TextView txtView = (TextView)vView;
txtView.TextSize = 14f;
txtView.SetTypeface(fontFace, TypefaceStyle.Normal);
}
}
}
}
}
}

Categories