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()
Related
I'm trying to do something when I click image displayed inside pictureBox1.
pictureBox is loaded with this code:
string imgpath = #"img\256.png";
pictureBox48.Image = Image.FromFile(imgpath);
Then control is released to me so I can see that the picture loaded correctly.
Then i click the picture:
public void pictureBox48_Click(object sender, EventArgs e)
{
string variable1 = pictureBox48.ImageLocation;
Form3 fo = new Form3(variable1);
fo.ShowDialog();
}
This doesn't work. When I debug the code I see that variable1 stay null, that is pictureBox48.ImageLocation is null. Why is that? Shouldn't it be the path to the image that is assigned there?
You can't get the image path when you set the image using the Image property because you are assigning an Image object which can come from different sources.
Set the image using ImageLocation.
string imgpath = #"img\256.png";
pictureBox48.ImageLocation = imgpath;
When you click in the PictureBox you can get the path using the same property:
public void pictureBox48_Click(object sender, EventArgs e)
{
string variable1 = pictureBox48.ImageLocation;
Form3 fo = new Form3(variable1);
fo.ShowDialog();
}
When dealing with Image or PictureBox I would recommend to not use something like Location or Path of the image. Assume that when the image is loaded user removes it from the hard drive and you're left with the code full of errors.
That's why you should rely on Image itself as it contains every information about the image like pixel format, width, height and raw pixel data.
I would recommend you to just copy the image, not the path to the file.
This piece of code should give you a hint:
pixtureBox48.Image = Image.FromFile(imgPath);
// above code assumes that the image is still on hard drive and is accessible,
// now let's assume user deletes that file. You have the data but not on the physical location.
Image copyImage = (Image)pictureBox48.Image.Clone();
Form3 fo = new Form(copyImage); // change .ctor definition to Form(Image copy)
fo.ShowDialog();
How can I add a click event to child objects I have created in my Code Behind?
String[] imageNames = System.IO.Directory.GetFiles("Assets/Images/Gallery");
foreach (String image in imageNames)
{
Uri source = new Uri("ms-appx:///" + image);
ImageSource imgSource = new BitmapImage(source);
Image myImage = new Image();
myImage.Source = imgSource;
gallery.Children.Add(myImage);
}
The above code gets all the images from the gallery folder and adds them to a variablesizedwrapgrid. I want to add a click event on each of these (to basically allow a user to save them to the device they are using)
Thanks
1)
myImage.PointerReleased += Img_PointerReleased;
private void Img_PointerReleased(object sender, PointerRoutedEventArgs e)
{
// do your job
}
2) or write UserControl wrapping Image that inherits from Button and add proper VisualStates if you don't want to have default button animations - this way you will be able to use Clicked event
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);
}
}
}
Is it possible to pin elements from an app to the Tiles page ? as in, the user can create a list in my app, and i would like to allow the user to pin elements from that list to the main tile page, is that possible ?
Thanks
For creating secondary tiles, you need to use the ShellTile.Create method.
Sample code:
string page = "/MainPage.xaml?id=" + itemId;
StandardTileData tileInfo = new StandardTileData
{
BackgroundImage = new Uri("ApplicationTile.png", UriKind.Relative),
Title = "Your tile title"
};
ShellTile.Create(new Uri(page, UriKind.Relative), tileInfo);
That will create a Tile with the specified item id.
Then, to get the item id when the user launches the app, check the NavigationContext.QueryString property.
Here is a tutorial: http://dotnet.dzone.com/articles/using-secondary-shell-tiles
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");
}
}
}