Obtain current page name in Xamarin Forms app - c#

I am currently trying to understand how to get the name of the (xaml) page I am currently into, with my Xamarin Form app.
How am I supposed to do it? I tried a variety of cases, even looking around the Internet, but nothing actually worked for me so far :/

This is just C# reflection - the name of the XAML page should match the name of it's class
var name = this.GetType ().Name;

You would (commonly) use wither a one page app (master/detail, tabs page) or a set of navigable pages, managed by a NavigationPage.
App.Current.MainPage would (normally) contain the first page shown and if it has .Navigation that would be the NavigationPage that can give you the most recently shown page - last one in the stack. If it doesn't you could assume your app being one page app.
All of the above is just "common" and not necessarily true in all cases, but gives you a starting point where to look for your current page.
var actionPage = App.Current.MainPage;
if (actionPage.Navigation != null)
actionPage = actionPage.Navigation.NavigationStack.Last();
actionPage.DisplayActionSheet(...)

I know that this has been resolved and the scenario is somewhat different but in my specific case I needed to identify the current page in the navigation stack from platform specific code so just in case it may help someone else, this is the code I used:
I used the title property that was set in the constructor of the page.
public static string GetCurrentPage()
{
var page = App.Navigation.NavigationStack.Last();
return page.Title;
}

You can get current open page.
1) if it's MainPage.
-> var MainPage = App.Current.MainPage as PageName;
2) if it's Navigation page.
you can get count pages.
App.Current.MainPage.Navigation.ModalStack.Count
var page= App.Current.MainPage.Navigation.ModalStack.LastOrDefault() as
PageName;
App.Current.MainPage.Navigation.NavigationStack.Count
var page1=App.Current.MainPage.Navigation.NavigationStack.LastOrDefault() as
PageName;

Here's how you can get the current page type from anywhere in the app (Xamarin Forms).
This might be a more general answer to your question but I thought it's worth posting.
If you're using:
1.App with Tabs/One Page
var mainPage = App.Current.MainPage as Xamarin.Forms.Shell;
var currentPage = mainPage.CurrentPage;
var type = currentPage.GetType().Name;
Also, URL of the current page:
string location = mainPage.CurrentState.Location.ToString()
2.Navigation Based Apps
As others also mentioned:
var mainPage = App.Current.MainPage;
var currentPage = mainPage.Navigation.NavigationStack.Last();
Hope it helps.

Related

FormsAppCompatActivity and custom ActionBar/ToolBar

I am working on a Xamarin.Forms app, where I was using a FormsApplicationActivity as my main activity and was able to customize the ActionBar with a custom view inside it (I put a Spinner in it, for some page)
But since there was a few UI / look and feel issues I upgraded to FormsAppCompatActivity.
Since I did that I just CAN'T get my spinner in the toolbar / actionbar! No matter what I try!
This was basically the previous code, wroking with FormsApplicationActivity
var activity = (Activity)this.Context;
var bar = activityActionBar;
var dlp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MatchParent, ViewGroup.LayoutParams.MatchParent);
bar.CustomView = new Android.Widget.Button(activity) {
Text = "Click",
LayoutParameters = dlp,
};
bar.DisplayOptions = ActionBarDisplayOptions.ShowCustom;
What should I write to support FormsAppCompatActivity please?
When using FormsAppCompatActivity the NavigationRenderer on android creates a new toolbar internally. It is a private field so far I can see and cannot be accessed.
here is the code : https://github.com/xamarin/Xamarin.Forms/blob/d1a8477233b28e6a20c6f5d4a75128ec2a05e6dc/Xamarin.Forms.Platform.Android/AppCompat/NavigationPageRenderer.cs
See image for the specific code part. I am also trying now to get access to view. So just a note the action bar you are trying to edit is the wrong one. That one is created on activity startup.
UPDATE: maybe found a solution look here : https://forums.xamarin.com/discussion/69923/access-to-the-formsappcompatactivity-bar

Moving newly created publishing page to top in MOSS 2007 programmaticaly

I am stuck with this problem for nearly one day now:
In an application, I create a publishing page in code:
PublishingPage newPage = pages.Add(usableName, layout);
newPage.ListItem["Title"] = promoRecord.PromotionName;
newPage.ListItem["Description"] = string.Empty;
newPage.Update();
newPage.CheckIn("First draft");
So far so good. The problem is, I need the newly created page to appear at the top of the navigation. I was naive enough to think something as simple as this:
SPNavigationNodeCollection navigationNodes = pWeb.CurrentNavigationNodes;
SPNavigationNode newNode = null;
foreach (SPNavigationNode node in navigationNodes)
{
if (node.Url.Equals(prefix + newPage.Url, StringComparison.OrdinalIgnoreCase))
{
newNode = node;
}
}
newNode.MoveToFirst(navigationNodes);
would work. It doesn't, because the page is simply not there (in the CurrentNavigationNodes collection).
So I tried with:
newNode = new SPNavigationNode(promoRecord.PromotionName, prefix + newPage.Url);
navigationNodes.AddAsFirst(newNode);
with no luck either - here I got an exception saying that I can't add the page because it's in DRAFT state. Actually, the CurrentNavigation seems to get updated when I go to the frontend management (Manage Content And Structure / Site Administration / Navigation) - and the page appears there. Even if it's in DRAFT mode.
I tried a lot of things with no success... maybe you guys have an idea what I could try?
Thanks a lot in advance!

Get URL Variables from a Frame and Pass to Codebehind

First off, yes I know I shouldn't be using frames, but I don't have a choice. It's an old system that's caused me nothing but headaches, but the network engineers love it and demand that this is where their information and pages have to go.
I'm currently using the .NET 4.0 framework, c#, and, though I doubt it matters for this question, SQL Server 2008R2.
The problem as it stands right now: I need a way to determine whether the primary or standby hardware is selected so I can properly set the radio button and initial information on page load to either the primary hardware or secondary hardware based on which page is loaded. The website my page is being used on is third party, which I do not have access to modifying, so I can't just tack URL variables onto that page or change settings.
The URL has variables, but they're generated statically elsewhere on the website and only visible inside the frame in which my page resides. I've never actually used frames, so I'm at a little bit of a loss. Worse, because of the way this is set up and being tested, I'm not actually sure how to set up any breakpoints in the code to see where it's failing.
I couldn't think of another way around this, but I would be more than happy to have a solution that doesn't involve this frame-y nonsense.
So far, I've been looking at these for guidance, but haven't had much success.
sharing variables between urls and frames, msdn's .NET 4.0 page on Frames,
a post on how to get url variables out of frames, and loading pages in IFrame dynamically from the codebehind.
For the time being, I've been asked to make sure the page as it stands does not break, which is why this is being checked instead of just done. It's currently in two places on that site, one without frames and URL variables (which the admins want to delete) and the new home with URL variables and frames. For now, the first one can't break, which is why you'll see a bit of strange checking and the ?? operator.
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
System.Web.UI.HtmlControls.HtmlGenericControl orionIFrame =
(System.Web.UI.HtmlControls.HtmlGenericControl)this.FindControl("pcmaframe");
if (orionIFrame != null)
{
string frameURL = orionIFrame.Attributes["src"].ToString() ?? "";
Uri frameURI = new Uri(frameURL);
NameValueCollection queryVars = HttpUtility.ParseQueryString(frameURI.Query);
//If this is in Orion, we want to change the canceller to standby if it's 97, not 96
if (queryVars["NetObject"] == "N:97" || queryVars["NetObject"] == "N%3a97")
{
SelectCanceller.SelectedValue = "Standby";
primaryStandby = false;
}
}
//Do some other stuff to generate page data
Right now, the code that generates the frame looks like this (where [url] replaces the actual url and [mypage] replaces the actual file name I've used):
NodeID - ${NodeID}<br>
Node Name - ${NodeName}
<iframe id="pcmaframe" src="[url]/[mypage].aspx?NetObject=N:" + ${NodeID} width = 1000 height = 1500>
</iframe>
At the moment, there is no bad behavior, it simply fails to switch. Both pages display the primary, regardless of the URL variables. The primary being N:96 and the secondary being N:97. The reason I check is that I'd like it to display something in the event that it fails, so it defaults to the primary hardware.
So, wonderful Stack Overflow people... Can you answer any of my three questions?
How can I troubleshoot a Frame on a separate website without adding output to the page when I have no way to insert breakpoints?
What can I do instead of using the URL variables and messing with these frames?
What logic am I missing or screwing up in my code that's causing the frame to /not/ recognize the URL variable?
UPDATE
Well, so far, I've determined that the frame is null. Not sure if this is because of the this.FindControl is not being properly cast, or it's due to the way the website uses frames, or any number of other things...
After being allowed to add some debugging output to the page, I was able to find a work around. What I believe is happening, based on some testing and these articles:
FindControl() return null
Better way to find control in ASP.NET
http://msdn.microsoft.com/en-us/library/txxbk90b%28v=vs.90%29.aspx
http://forums.asp.net/t/1097333.aspx
http://msdn.microsoft.com/en-us/library/system.web.ui.page.previouspage.aspx
Is that the website where my program/page is being used has the frame at a higher level than my ASP has access to without a lot of technical voodoo. Since the frame wasn't returning, I started testing and found that the calling frame was actually using [URL].[MyPage].aspx?NetObject=N:97 as the previous page or the calling page. This was true under a variety of circumstances which meant it was semi-safe to use Request.UrlReferrer:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
string frameURL = Request.UrlReferrer.ToString() ?? "NO DATA";
if ((frameURL != null) && (frameURL != "NO DATA"))
{
Uri frameURI = new Uri(frameURL);
NameValueCollection queryVars = HttpUtility.ParseQueryString(frameURI.Query);
//If this is in Orion, we want to change the canceller to standby if it's 97, not 96
if (queryVars["NetObject"] == "N:97" || queryVars["NetObject"] == "N%3a97")
{
SelectCanceller.SelectedValue = "Standby";
primaryStandby = false;
}
}

Sharepoint - upgrade webpart properties

I'm playing with SharePoint 2010 now and have a problem.
There is a feature that is responsible for webparts - it's scope is web. It's needed to update some properties of already created webparts, for example - title.
So I've overridden FeatureUpgrading event and added custom upgrade action into feature manifest - there is no problem here.
In that feature receiver I plan to have a code that should get the file with needed page, check it out, iterate through all the web parts on it, change property and then check in page back.
The problem is that all my webparts appear as ErrorWebPart with empty title.
By the way, if I use the same code in FeatureDeactivating event - everything works good.
The only difference I've noticed - in featureupgrading HttpContext.Current was null. So I've populated it manually but it didn't help.
While googling, the only two advices were: populate HttpContext and ensure that libs with webparts are in GAC. Both conditions are done in my situation.
The sample code from FeatureUpgrading is as proper:
SPUtility.ValidateFormDigest();
web.AllowUnsafeUpdates = true;
var request = new HttpRequest("", web.Url, "");
HttpContext.Current = new HttpContext(request, new HttpResponse(new StringWriter()));
HttpContext.Current.Items["HttpHandlerSPWeb"] = web;
var fileUrl = web.Url + "/pages/sample.aspx";
var file = web.GetFile(fileUrl);
if (file.CheckOutType == SPFile.SPCheckOutType.None)
{
file.CheckOut();
}
using (var webPartsManager = file.GetLimitedWebPartManager(PersonalizationScope.Shared))
{
foreach (WebPart webPart in webPartsManager.WebParts)
{
Console.WriteLine(webPart.GetType().ToString());
}
}
file.CheckIn("System update");
Would appreciate any help. Maybe there is something I'm missing or there is another variant to accomplish described task?
Regards.
Since it is working on Deactivating(), I think the order in which the features are activated is the problem.
You may have to ensure the below:
1. First activate the Feature that adds the webparts
2. Then activate the new feature.
You can change this in package. Or better add a dependency to your new feature.

Loading dynamically RESX file not working

I have a webpage that has to be displayed in several different languages based on user selection. For that, I'm using RESX files for each of the asp.net webpages. I don't want to used the automatic detection of the language in the browser, but I want to set the language, again, based in the user selection. In order to accomplish this I'm doing the following:
Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("es-MX", false);
Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("es-MX", false);
OR
Page.Culture = "es-MX";
Page.UICulture = "es-MX";
But neither of those are working as expected! I'm initializing the Culture in the Init method of the page but it will always display the default language. I'm inspecting the values of those properties and those have the culture correctly, but still is not being rendered using the RESX file. Any ideas? Suggestions?
Thanks
In case someone runs into this issue when working with Explicit localization, here is what has to be done:
protected override void InitializeCulture()
{
Page.Culture = "en-US";
Page.UICulture = "en-US";
}
From the net-tutorials.com website:
Since the Page directive is just a shortcut to the Page class, this can be done from CodeBehind as well. However, we have to do it at a certain point, before the page is being rendered, to make sure that it has the desired effect. This is where the InitializeCulture() method comes into play, a method that is called by ASP.NET pretty early in the Page life cycle, which you can override.
Try this
System.Resources.ResourceReader resourceReader
= new System.Resources.ResourceReader("RES_PATH");
Now you can use this to load users language like es.resx
System.Resources.ResourceReader resourceReader
= new System.Resources.ResourceReader(HttpContext.Current.Request.UserLanguages[0]
+ ".resource");

Categories

Resources