pin webbrowser instance to start screen - c#

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");
}
}
}

Related

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 update MapCenter in windows phone 8.1 WinRT App with MyMap.Mapcenter

Please help me.
the scenario is there are two pages in my app one is map page(MainPage.xaml) and other is map location search page(LocationSearch.xaml) when i run the app on my phone map center location is update as i want but when i go to second page and searching the location and back to the map page with the new location co-ordinates the map center location is not updating
protected override void OnNavigatedTo(NavigationEventArgs e)
{
// TODO: Prepare page for display here.
// TODO: If your application contains multiple pages, ensure that you are
// handling the hardware Back button by registering for the
// Windows.Phone.UI.Input.HardwareButtons.BackPressed event.
// If you are using the NavigationHelper provided by some templates,
// this event is handled for you.
if (e.Parameter != null)
{
BinMapPins.AppData.Resultclass myobject = e.Parameter as BinMapPins.AppData.Resultclass;
BasicGeoposition locPos = new BasicGeoposition();
if (myobject != null)
{
System.Diagnostics.Debug.WriteLine("lat " + myobject.address);
System.Diagnostics.Debug.WriteLine("lat " + myobject.lat);
System.Diagnostics.Debug.WriteLine("lang " + myobject.lang);
locPos.Latitude = myobject.lat;
locPos.Longitude = myobject.lang;
areaInfo.Text = myobject.address;
MyMap.Children.Clear();
Geopoint gopoints = new Geopoint(locPos);
MyMap.Center = gopoints;
System.Diagnostics.Debug.WriteLine("geo point val: " + gopoints.Position.Latitude);
MyMap.ZoomLevel = 16;
}
}
else
{
callMap();
}
}

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()

How to pass value from one page to another page in the context of data binding?

I am creating an app where we have a Data Template list of building names and when clicked on say "Thomas Gosnell Hall", it will go to a new page with the TextBlock changed to that of the selected building name "Thomas Gosnell Hall". I know data binding is used to do this, but how do I do it across two different pages?
MainPage.xaml
<TextBlock Tap="TextBlock_Tap" Text="{Binding LineOne}" TextWrapping="NoWrap" Style="{StaticResource PhoneTextExtraLargeStyle}"/>
MainPage.xaml.cs (When a user taps on the building name, it will navigate to new page)
public void TextBlock_Tap(object sender, System.Windows.Input.GestureEventArgs e)
{
var building = ((TextBlock)sender).Text; // gets information based on the tapped building
//perform action based on information about the tapped building
if(building == "Thomas Gosnell Hall")
{
//MessageBox.Show("08 - (GOS)");
NavigationService.Navigate(new Uri("/MapLocation.xaml?building=" + building, UriKind.Relative)); // pass the string value to destination page through Uri parameter
}
else if(building == "Lyndon Baines Johnson Hall")
{
MessageBox.Show("060 - (LBJ)");
}
}
MapLocation.xaml
<TextBlock x:Name="buildingName" Text="Building Name" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
MapLocation.xaml.cs (The new page after the user selected the building name)
/**
* How to: Create the Binding (behind code)
* Source: http://msdn.microsoft.com/en-us/library/cc838207%28v=vs.95%29.aspx?cs-save-lang=1&cs-lang=csharp#code-snippet-1
*/
// Define source object
public class Building
{
public string BuildingName { get; set; }
}
public MapLocation()
{
InitializeComponent();
Loaded += MapLocation_Loaded;
/* // create an instance of the source object
Building bldg = new Building();
bldg.BuildingName = building; // value to change depending on user's click
// create a binding object
Binding MyBinding = new Binding();
// set the binding properties on the binding object
MyBinding.Path = new PropertyPath("BuildingName");
MyBinding.Mode = BindingMode.OneTime;
// set the source of the binding by setting the DataContext property
buildingName.DataContext = bldg;
// attach the binding to the property of the FrameworkElement
buildingName.SetBinding(TextBlock.TextProperty, MyBinding);*/
}
private void MapLocation_Loaded(object sender, RoutedEventArgs e)
{
//throw new NotImplementedException();
string building;
if(NavigationContext.QueryString.TryGetValue("building", out building))
{
//load information based on building parameter value
buildingName.Text = building;
}
}
/*public MapLocation_Loaded()
{
string building;
if(NavigationContext.QueryString.TryGetValue("building", out building))
{
//load information based on building parameter value
}
}*/
The problem lies within this line bldg.BuildingName = building; as it says The name building does not exist in the current context. It exists in the MainPage.xaml.cs, but not in MapLocation.xaml.cs. How do I data bind the building name depending on the user's tapped choice of building onto the next page?
I would suggest to pass the string value to destination page through Uri parameter :
public void TextBlock_Tap(object sender, System.Windows.Input.GestureEventArgs e)
{
var building = ((TextBlock)sender).Text;
NavigationService.Navigate(new Uri("/MapLocation.xaml?building=" + building, UriKind.Relative));
}
Then handle loading correct informations in the destination page, for example in page Loaded event handler :
public MapLocation_Loaded()
{
string building;
if(NavigationContext.QueryString.TryGetValue("building", out building))
{
//load information based on building parameter value
}
}
One option is to expose the selected value on MainPage as a public property. Then other pages can just read whatever value was set.
The other option is to pass it as state in the navigate method:
NavigationService.Navigate(new Uri("/MapLocation.xaml", UriKind.Relative), building);
see here: http://msdn.microsoft.com/en-us/library/ms591042(v=vs.110).aspx

Secondary Tile Navigation Windows Phone 8

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);
}
}
}

Categories