Secondary Tile Navigation Windows Phone 8 - c#

i have a problem when i navigate from a secondary tile into my app. The tile is created and has a navigation uri. Now i have a problem:
On "navigateTo" i test the navigationcontext for a specific string. If the string has the number i call this number. The first problem i have is when i navigate to an other page inside the app (after first click on secondary tile) and then return back to mainpage, it also tries to call the number, because the navigationcontext is the same as when i click the secondary tile.
If i clear the navigationcontext after the first click on secondary tile the navigation works. But if i pause the app and than click the secondary tile again the navigationcontext is empty and so no number is called.
Create of tile
IconicTileData tileData = new IconicTileData
{
Title = App.MainViewModel.SelectedPOI.Name,
SmallIconImage = new Uri("/Assets/Images/feature.phone.png", UriKind.Relative),
WideContent1 = App.MainViewModel.SelectedPOI.Name,
WideContent2 = App.MainViewModel.SelectedPOI.Telefonnumber,
WideContent3 = App.MainViewModel.SelectedPOI.Street
};
if (App.MainViewModel.SelectedPOI.Id == -1)
tileData.BackgroundColor = Helper.GetColorFromHexString("#E46D1D");
else
tileData.BackgroundColor = Helper.GetColorFromHexString("#4FAE32");
string SecondaryTileUriSource = String.Format("Source={0}&ID={1}", TILESTATUS, App.MainViewModel.SelectedPOI.Id);
//check if tile exist
ShellTile tile = Helper.FindTile(SecondaryTileUriSource);
if (tile == null)
{
// having a unique NavigationUri is necessary for distinguishing this tile
string tileUri = string.Concat("/MainPage.xaml?", SecondaryTileUriSource);
ShellTile.Create(new Uri(tileUri, UriKind.Relative), tileData, true);
}
OnNavigateTo - MainPage
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
string status = String.Empty;
if (NavigationContext.QueryString.TryGetValue("Source", out status))
{
MainPivot.SelectedItem = AlarmPivotItem;
//App.MainViewModel.StartAlarm();
//or
//get the number from source/status...
App.MainViewModel.CallNumber(12345);
//NavigationContext.QueryString.Clear();
}
}
Has anybody an example where e.g. a Number is called from a secondary tile and there are maybe at least 2 pages inside the app?
Any other sugestion where the problem can be?
Thank you

Rather than clearing the navigation context, you can use the NavigationMode property to know whether it's a new navigation to the page (for instance, form the secondary tile) or if the user went back from another page:
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
if (e.NavigationMode != System.Windows.Navigation.NavigationMode.Back)
{
if (NavigationContext.QueryString.TryGetValue("Source", out status))
{
MainPivot.SelectedItem = AlarmPivotItem;
//App.MainViewModel.StartAlarm();
//or
//get the number from source/status...
App.MainViewModel.CallNumber(12345);
}
}
}

Related

Xamarin Navigation Bar Hide Hamburger Menu

I need to hide the hamburger menu on certain pages but still display information in then navbar. I don’t know of any way to accomplish this.
Also, I need the navbar to stay fixed to the top of the screen but it’s getting cut off when the keyboard pops up.
How can I go about this?
FlyoutPage.ShouldShowToolbarButton method is used to determine whether to show/hide hamburger icon , and it is triggered every time when selecting pages.
We can define a bool field ,change its value when directing to specific pages.
FlyoutPage
public override bool ShouldShowToolbarButton()
{
return showIcon;
}
private bool showIcon = true;
private void ListView_ItemSelected(object sender, SelectedItemChangedEventArgs e)
{
var item = e.SelectedItem as FlyoutPage1FlyoutMenuItem;
if (item == null)
return;
var page = (Page)Activator.CreateInstance(item.TargetType);
page.Title = item.Title;
Detail = new NavigationPage(page);
IsPresented = false;
FlyoutPage.ListView.SelectedItem = null;
//add this logic
showIcon = (item.Id == 1) ? false : true; //only the second page do not show hamburger icon
}

Xamarin clickable substring in custom label

I am trying to make it so users can click a certain substring in a label and it would run a method, for example clicking #hashtag would run OpenHashtag(string hashtagand clicking a #taggedUser would run ViewProfile(taggedUser)
I found this tutorial, except I don't want phone numbers or URLs to be clickable, only hashtags and tagged users.
These are the renders its using
Android
[assembly: ExportRenderer(typeof(BodyLabel), typeof(BodyLabelAndroid))]
namespace SocialNetwork.Droid.Renderers
{
public class BodyLabelAndroid : LabelRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Label> e)
{
base.OnElementChanged(e);
var view = (BodyLabel)Element;
if (view == null) return;
TextView textView = new TextView(Forms.Context);
textView.LayoutParameters = new LayoutParams(LayoutParams.WrapContent, LayoutParams.WrapContent);
textView.SetTextColor(view.TextColor.ToAndroid());
// Setting the auto link mask to capture all types of link-able data
textView.AutoLinkMask = MatchOptions.All;
// Make sure to set text after setting the mask
textView.Text = view.Text;
textView.SetTextSize(ComplexUnitType.Dip, (float)view.FontSize);
// overriding Xamarin Forms Label and replace with our native control
SetNativeControl(textView);
}
}
}
IOS
[assembly: ExportRenderer(typeof(BodyLabel), typeof(BodyLabeliOS))]
namespace SocialNetwork.iOS.Renderers
{
public class BodyLabeliOS : ViewRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<View> e)
{
base.OnElementChanged(e);
var view = (AwesomeHyperLinkLabel)Element;
if (view == null) return;
UITextView uilabelleftside = new UITextView(new CGRect(0, 0, view.Width, view.Height));
uilabelleftside.Text = view.Text;
uilabelleftside.Font = UIFont.SystemFontOfSize((float)view.FontSize);
uilabelleftside.Editable = false;
uilabelleftside.DataDetectorTypes = UIDataDetectorType.All;
uilabelleftside.BackgroundColor = UIColor.Clear;
SetNativeControl(uilabelleftside);
}
}
}
Android:
Instead of using textView.AutoLinkMask = MatchOptions.All
you can use
Linkify.AddLinks method. Define your regular expression (for example, any word which starts with # or #) and it will work.
But on iOS, it is more complicated I think.
There I see two options:
Use WebView. Parse your string and add "<a href" where needed.
Break your text to pieces and add separate labels for each clickable part. If you want to click only hashtags and tagged users you can add the appropriate labels just below the text. Afterwards you can add tap gesture recognizers to handle the clicks.

Cocossharp Template not working

I'm new to cocossharp. I installed cocossharp templates for visual studio, when i select a new cocossharp android game, and run the application, all I get is a black screen with a logo at the top. From the code, I believe i am supposed to get a blue screen with a label written
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.Main);
// Get our game view from the layout resource,
// and attach the view created event to it
CCGameView gameView = (CCGameView)FindViewById(Resource.Id.GameView);
gameView.ViewCreated += LoadGame;
}
void LoadGame(object sender, EventArgs e)
{
CCGameView gameView = sender as CCGameView;
if (gameView != null)
{
var contentSearchPaths = new List<string>() { "Fonts", "Sounds" };
CCSizeI viewSize = gameView.ViewSize;
int width = 1024;
int height = 768;
// Set world dimensions
gameView.DesignResolution = new CCSizeI(width, height);
// Determine whether to use the high or low def versions of our images
// Make sure the default texel to content size ratio is set correctly
// Of course you're free to have a finer set of image resolutions e.g (ld, hd, super-hd)
if (width < viewSize.Width)
{
contentSearchPaths.Add("Images/Hd");
CCSprite.DefaultTexelToContentSizeRatio = 2.0f;
}
else
{
contentSearchPaths.Add("Images/Ld");
CCSprite.DefaultTexelToContentSizeRatio = 1.0f;
}
gameView.ContentManager.SearchPaths = contentSearchPaths;
CCScene gameScene = new CCScene(gameView);
gameScene.AddLayer(new GameLayer());
gameView.RunWithScene(gameScene);
}
}
public class GameLayer : CCLayerColor
{
// Define a label variable
CCLabel label;
public GameLayer() : base(CCColor4B.Blue)
{
// create and initialize a Label
label = new CCLabel("Hello CocosSharp", "Fonts/MarkerFelt", 22, CCLabelFormat.SpriteFont);
// add the label as a child to this Layer
AddChild(label);
}
protected override void AddedToScene()
{
base.AddedToScene();
// Use the bounds to layout the positioning of our drawable assets
var bounds = VisibleBoundsWorldspace;
// position the label on the center of the screen
label.Position = bounds.Center;
// Register for touch events
var touchListener = new CCEventListenerTouchAllAtOnce();
touchListener.OnTouchesEnded = OnTouchesEnded;
AddEventListener(touchListener, this);
}
void OnTouchesEnded(List<CCTouch> touches, CCEvent touchEvent)
{
if (touches.Count > 0)
{
// Perform touch handling here
}
}
}
I put a break point in the method thats called when the event ViewCreated is fired, the breakpoint is never hit. I tried creating the CCGameView first then then registering the eventhandler because I thought the event was firing before registering
CCGameView gameView = new CCGameView(this);
gameView.ViewCreated += LoadGame;
gameView = (CCGameView)FindViewById(Resource.Id.GameView);
then I tried calling the LoadGame method directly
CCGameView gameView = (CCGameView)FindViewById(Resource.Id.GameView);
gameView.ViewCreated += LoadGame;
LoadGame(gameView, EventArgs.Empty);
but this resulted in a null exception for the gameView.ContentManager.
My only other suspicion is the emulator itself, perhaps it needs something installed extra, however for a normal xamarin android project it works perfectly. Iv also tried looking at the various examples on Xamarin but they all use Application Delegate, which if i'm not mistaken, was the old way of doing thing. If anyone can help, Id appreciate it. Thanks
It was an emulator issue, had to check the Use Host GPU option on the emulator. On the Android Virtual Device Manager where I can select my created emulators, I selected an emulator I had created, then instead of starting it, I first Edited it, that's where I found the option (Since I had already created some emulators). The answer is here

Unable to set multiple secondary tiles in windows phone 8

I want to be able to pin page from where the user has navigated to, I want to make its content shows dynamically depending on which item the user has selected to pin. The first secondary tile, I could do it, but the problem is that when there are more than one secondary tile at the start menu, all the secondary tiles are link to the page but the content of the page is all the same as the last secondary tile.
Here is what I do:
From where the page is navigated to, I receive the information and set it display on the page like this:
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
if (!IsolatedStorageSettings.ApplicationSettings.Contains("isolated_image"))
{
IsolatedStorageSettings.ApplicationSettings.Add("isolated_image", NavigationContext.QueryString["pro_image"] as string);
}
![enter image description here][1]
imageBase = (IsolatedStorageSettings.ApplicationSettings["isolated_image"] as string);
StreamResourceInfo sri = null;
Uri uri = new Uri(imageBase, UriKind.Relative);
uriString = uri.ToString();
sri = Application.GetResourceStream(uri);
BitmapImage bitmap = new BitmapImage();
bitmap.SetSource(sri.Stream);
base64 = ((App)Application.Current).ImageToBase64(bitmap);
item_image.Source = ((App)Application.Current).ImageFromBase64(base64);
if (!(IsolatedStorageSettings.ApplicationSettings.Contains("item_name")))
{
IsolatedStorageSettings.ApplicationSettings.Add("item_name", PhoneApplicationService.Current.State["pro_name"]);
}
ShellTile secondaryTile = this.FindTile(SecondaryTileUriSource);
if (secondaryTile != null)
{
item_image.Source = ((App)Application.Current).ImageFromBase64(base64);
}
txtb_product_name.Text = PhoneApplicationService.Current.State["pro_name"] as string;
}
From information I got, when the user press on pin app bar, I create the secondary tile with the unique uri based on "?image_item="+imageBase
void btnPin_Click(object sender, EventArgs e)
{
ShellTile tile = this.FindTile(SecondaryTileUriSource);
if(tile==null)
{
StandardTileData tileData = this.GetSecondaryTileData();
Uri uri = new Uri("/All Files/Product Files/Dry/Product Detail.xaml?item_image=" + imageBase, UriKind.Relative);
MessageBox.Show("the link uri is "+ uri.ToString());
ShellTile.Create(uri, tileData);
}
}
At the end, when I have have multiple secondary tiles at the start menu, the first, and the second secondary tiles will displays the same content on the page like this last secondary tile that I pinned.
I'm sure that the link uri is already unique; otherwise, I could not create multiple secondary tiles. Can anyone help me what's wrong? Thanks
First, I'd change your pinning logic and instead of creating string from your image data use some sort of ID to identify image... You current approach is unnecessary complicated.
It could be as simple as to have: image1,image2, image3 and so on. Then get id from query string and construct image uri like: new Uri("../image" + id)
If you have successfully created multiple secondary tiles, then each must be unique and your problem probably lies in parsing query strings in your OnNavigatedTo()

pin webbrowser instance to start screen

Basically what I am trying to accomplish is to pin a webbrowser instance to my windows phone start screen, and then when someone wants to go back to the specific site that was pinned, the user will click on the tile and be taken to that same webpage within my application when the application reloads. I have researched this functionality all over the internet and have not found any utilization of this, but I have seen this performed on a few apps in the marketplace.
I have attempted to reference someone's implementation of something similiar using a querystring to get the required data to tell the application how to load from the secondary tile, but I may have something incorrect. Also, I can tell the secondary tile to load up the main page in my application which contains a webbrowser control, but I have not figured out how I can send a link to the webbrowser control (via querystring?) to load a particular webpage. My code thus far is as follows
MainPage.xaml.cs
public partial class MainPage : PhoneApplicationPage
{
//for 'pin to start' webbrowser instance
private const string _key = "url";
private string _url;
// Constructor
public MainPage()
{
InitializeComponent();
}
//OnNavigatedFrom method
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
//base.OnNavigatedFrom(e);
try
{
if (_url != null)
{
this.State[_key] = new MainPage
{
_url = TheBrowser.Url.AbsoluteUri.ToString()
};
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
//OnNavigatedTo method
protected override void OnNavigatedTo(NavigationEventArgs e)
{
//base.OnNavigatedTo(e);
// See whether the Tile is pinned
// (User may have deleted it manually.)
//ShellTile TileToFind = ShellTile.ActiveTiles.FirstOrDefault(x => x.NavigationUri.ToString().Contains("DefaultTitle=FromTile"));
//for "pin to start" webbrowser instances
//if this page was activated from a tile, launch a request for the current
//web address at the location indicated in the query string
if (NavigationContext.QueryString.ContainsKey(_key))
{
string url = NavigationContext.QueryString[_key];
//if url is absoluteuri, open webbrowser and direct to absoluteuri
if (!TheBrowser.InitialUri.Equals(TheBrowser.InitialUri))
{
TheBrowser.Navigate(url);
}
//remove the url from the querystring (important!!)
NavigationContext.QueryString.Remove(_key);
}
//otherwise check to see if the app needs to be untombstoned
//and restore it to its pretombstoned state if it does
//else if (_url == null)
else if (_url == null && this.State.ContainsKey(_key))
{
MainPage mainPage = this.State[_key] as MainPage;
//TheBrowser.Navigate(TheBrowser.InitialUri);
_url = (string)mainPage.State[_key];
TheBrowser.Navigate(_url);
}
}
//Application Tile
private void SetApplicationTile(object sender, EventArgs e)
{
int newCount = 0;
string appName = "Quest";
// Application Tile is always the first Tile, even if it is not pinned to Start.
ShellTile TileToFind = ShellTile.ActiveTiles.First();
// Application should always be found
if (TileToFind != null)
{
// Set the properties to update for the Application Tile.
// Empty strings for the text values and URIs will result in the property being cleared.
StandardTileData NewTileData = new StandardTileData
{
Title = appName,
BackgroundImage = new Uri("/Background.png", UriKind.Relative),
Count = newCount,
BackTitle = appName,
BackBackgroundImage = new Uri("", UriKind.Relative),
BackContent = "flipside"
};
// Update the Application Tile
TileToFind.Update(NewTileData);
}
}
//Secondary Tile(s)
private void PinToStart_Click(object sender, EventArgs e)
{
//Look to see whether the Tile already exists and if so, don't try to create it again.
// if the Tile doesn't exist, create it
//if (!String.IsNullOrEmpty(_url))
//{
// Look to see whether the Tile already exists and if so, don't try to create it again.
ShellTile TileToFind = ShellTile.ActiveTiles.FirstOrDefault(x => x.NavigationUri.ToString().Contains("url=" + _url));
//ShellTile TileToFind = ShellTile.ActiveTiles.FirstOrDefault(x => x.NavigationUri.ToString().Contains("_url"));
// Create the Tile if we didn't find that it already exists.
if (TileToFind == null)
{
StandardTileData NewTileData = new StandardTileData
{
BackgroundImage = new Uri("Background.png", UriKind.Relative),
Title = "link",
Count = 1,
BackTitle = "Quest",
BackContent = (string)_url,
BackBackgroundImage = new Uri("", UriKind.Relative)
};
// Create the Tile and pin it to Start. This will cause a navigation to Start and a deactivation of our application.
ShellTile.Create(new Uri("/MainPage.xaml?" + _key + "=" + _url, UriKind.Relative), NewTileData);
//ShellTile.Create(new Uri("/MainPage.xaml?_url", UriKind.Relative), NewTileData);
}
//}
}
}
As you can see, I am new to the secondary tile creating and implementation. I have been playing around with the correct structure, and I am attempting to use a querystring to pass the url with the secondary tile to load the webbrowser on MainPage.xaml with the correct website. What I have so far actualy does create a secondary tile and does bring me back to the MainPage.xaml but with a new instance of my webbrowser which is set to an initialuri of http://www.bing.com.
Any help with this would be GREATLY appreciated. I have been working on this for a while and have seen several ways to create the secondary tile for certain xaml pages, but nothing requiring loading a webbrowser control with a certain url. I need to implement this solution quickly! Could you please also include changes in code because I am definately a newcomer to wp7! Thanks in advance for your much appreciated help.
I'm one of the dev's on MegaTile (which does exactly what you describe above).
We have two pages:
Main.xaml - this does the management of the tiles and setting up the actions
CallbackHandler.xaml - this handles the launch from the secondary tiles.
When we are creating a new tile (your PinToStart_Click) we create the callback as:
ShellTile.Create(new Uri("/CallbackHandler.xaml?Action=" + _action, UriKind.Relative), NewTileData);
Then in the CallbackHandler.xaml.cs PhoneApplicationPage_Loaded we do the appropriate action:
try
{
UriBuilder b = new UriBuilder(extraData);
new WebBrowserTask { Uri = b.Uri }.Show();
}
catch (Exception ex)
{
// something useful
}
Edit: a bit more time so I made your example work:
XAML:
<!--ContentPanel - place additional content here-->
<StackPanel x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0" >
<TextBox x:Name="url" Text="http://www.linknode.co.uk" />
<Button Content="Create Tile" Click="PinToStart_Click" />
<phone:WebBrowser x:Name="TheBrowser" Height="400" />
</StackPanel>
c#
public partial class MainPage : PhoneApplicationPage
{
private const string _key = "url";
// Constructor
public MainPage()
{
InitializeComponent();
}
//OnNavigatedTo method
protected override void OnNavigatedTo(NavigationEventArgs e)
{
//if this page was activated from a tile it will contain a Querystring value of _key
// launch a request for the current web address at the location indicated in the query string
if (NavigationContext.QueryString.ContainsKey(_key))
{
string url = NavigationContext.QueryString[_key];
TheBrowser.Navigate(new Uri(url));
}
}
private void PinToStart_Click(object sender, RoutedEventArgs e)
{
string _url = url.Text;
ShellTile TileToFind = ShellTile.ActiveTiles.FirstOrDefault(x => x.NavigationUri.ToString().Contains("url=" + _url));
// Create the Tile if we didn't find that it already exists.
if (TileToFind == null)
{
StandardTileData NewTileData = new StandardTileData
{
BackgroundImage = new Uri("Background.png", UriKind.Relative),
Title = string.Format("link - {0}", _url),
Count = 1,
BackTitle = "Quest",
BackContent = (string)_url,
BackBackgroundImage = new Uri("", UriKind.Relative)
};
// Create the Tile and pin it to Start. This will cause a navigation to Start and a deactivation of our application.
ShellTile.Create(new Uri("/MainPage.xaml?" + _key + "=" + _url, UriKind.Relative), NewTileData);
}
else
{
MessageBox.Show("Tile already exists");
}
}
}

Categories