Running code after xaml page close - c#

I'm writing a music player app for WP8 in XAML and C#, but coming from a winforms background I don't know how to do the following.
My main page opens a separate page to display the tracks of a music album. The user can select some of these tracks which then get added to a central playlist which is working fine, but I want the main page to call its playlist refresh function when the song selection page is closed.
If I was doing this as winforms I would do something like:
private void ShowAlbumPage(Int16 albumId)
{
albumPage.albumId = albumId;
albumPage.ShowDialog();
RefreshPlaylist();
}
But this will not work for XAML
I currently have this:
private void ShowAlbumPage(Int16 albumId)
{
NavigationService.Navigate(new Uri("/AlbumPage.xaml?albumId=" + albumId.ToString(), UriKind.Relative));
}
Any suggestions on how and when to call RefreshPlaylist?

Its a vague idea ,but i think if i share i can also improve. You could pass the List to the AlbumPage (Current collection) , if user add a song to playlist , add this to the collection , when returning just send back the collection and update the Home Page.
// MainPage.Xaml
private void list_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
SongsList selectedItemData = SelectedItem as SongsList ;
if(selectedItemData != null)
{
NavigationService.Navigate(new Uri(string.Format("/AlbumPage.xaml?parameter={0}",selectedItemData.ID ), UriKind.Relative));
}
}
//AlbumPAge.Xaml
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
base.OnNavigatedTo(e);
string parameter = this.NavigationContext.QueryString["parameter"];
SongsList country = null;
// GETS THE SONG COLLECTION HERE , UPDATE WHEN USER ADD TO PLAYLIST , AND RETURN BACK.
}
**If your doing on MVVM Way .This is just an Idea not tested.**
There is view-model it contains Collection of Songs, Maintain the same view-model over the two pages , Update the Song collection so Mainpage UI will automatically gets updated.
ViewModel Maintain the same over the Album Page.
ObservableCollection<Songs> _songs=new ObservableCollection<Songs>();
_songs.Add(new songs{Artist="ArtistName",Album="AlbumName"});
// AlbumPage CodeBehind.
private AddSongtoPlaylist(Song currentSong)
{
_songs.Add(currentSong);
}
Reference

Some of the ways you could accomplish this:
Add the newly selected songs on the Application level on the PhoneApplicationService.State Dictionary. Whenever you return to the main page, load the transient state that will include the added songs.
Save them on a variable on the Application level and whenever navigating to the main page load the playlist.
Store them in the IsolatedStorage and load them whenever you navigate to the main page.
Pass them back to your main page through the navigation QueryString.
The method you choose is just a matter of personal preference.

I think I have found a reasonably simple workaround - I have just put a call to RefreshPlayQueue() in the OnNavigatedTo method of MainPage.xaml. This seems to work

Related

Which event is fired when Content property is changed

I have two Pages ProductSearch,ProductDetail and Im changing the Content property to Navigate between Pages. I want to know if any events are fired so I can write some code in it?
On ProductDetail Page I have UIElement property
public UIElement MainContent { get; set; }
On ProductSearch Page I Navigate to ProductDetail By setting the Content property like this:
private void OnGetDetailsClick(object sender, RoutedEventArgs e)
{
ProductDetail productDetail = new ProductDetail();
productDetail.MainContent = this.Content;
this.Content = productDetail;
}
On ProductDetail Page's Back Button I navigate back to ProductSearch:
private void OnBackButtonClick(object sender, RoutedEventArgs e)
{
this.Content = MainContent;
}
Now I want to know how can I call a method when I navigate Back to ProductSearch Page i.e how would I know that I have Navigated from ProductDetail Page? I tried to check if it loads the page but found out that When you change content of control it doesn't fire the load event of the page. Any solution?
Yea this will not execute the load event since your are only changing the content obviously.
if you want to take advantage of navigation you should check out this video. Even if its done with blend the concepts apply also with Visual STudio: https://vimeo.com/6599527 (Simple Silverlight Master/Detail Navigation App with Blend 3)
You should check out articles on master detail binding like this one: https://msdn.microsoft.com/en-us/library/cc645060(v=vs.95).aspx
The key is to take advantage of the powerful binding concepts which come with silverlight. And if you are not using deep linking you might want to consider using a user control to hide/show details instead of a extra page.
HTH

Set value of an object based on combobox selection (xaml / c#, uwp)

Essentially, what I'm trying to do is take a selected item from a combobox on Page 1 and set the image source on Page 2 based on that selection, but I'm not exactly sure how to make this happen.
On Page 1 I have:
private void pOneColorChoice(object sender, SelectionChangedEventArgs e)
{
setPlayerOneColor = PlayerOneColor.SelectedItem;
}
On Page 2 I'm not sure how to call that selection and then fit it into this to set the image:
BitmapImage ImageOne;
if (PlayerOneColor == Black)
{
ImageOne = new BitmapImage(new Uri("Assets/Black.jpg"));
PlayerOneImage.Source = ImageOne;
}
I would add other statements for the other color choices. I'm probably way off but any suggestions would be greatly appreciated!
When you are navigating to the Page2 you can send it as a parameter
private void pOneColorChoice(object sender, SelectionChangedEventArgs e)
{
setPlayerOneColor = PlayerOneColor.SelectedItem;
Frame.Navigate(typeof(Page2), setPlayerOneColor);
}
Here in Page 2 Navigation Method you can get your parameter like this
var name = e.NavigationParameter as yourType;
As has been answered here, you can pass your option as a parameter when you navigate to the page.
I'd recommend taking a look at following an MVVM design pattern for your application though, this way you can access your other page's view model from other pages. MVVM Light is a great starting point.
Doing it with this method will let your have one view model for your settings page where you choose your option, and then from the other, you'd access that same property which you've changed. I can go into more detail if required :)

Correct way to transfer SelectedItemViewModel to another page in Windows Phone 8.1

I'm currently building a universal app but I'm concentrating on the WP8.1 part of it right now. I'm using MVVMLight with this project.
For simplicity sake, we'll just assume that I only have 2 pages in the project.
Page1.xaml contains a list which has various items. The Page1.xaml is binded to its own ViewModel i.e. Page1ViewModel. Each item in the list represents a viewModel i.e. ItemViewModel.
When I tap on an item, I call the following code:
public RelayCommand<ItemViewModel> ItemTapCommand
{
get
{
return this._itemTapCommand ?? (this._itemTapCommand =
new RelayCommand<ItemViewModel>((msg) =>
ExecuteItempTapCommand(msg)));
}
}
When an item in the list is tapped, I call the following code:
private object ExecuteItempTapCommand(ItemViewModel selectedItemViewModel)
{
Page2ViewModel page2ViewModel =
SimpleIoc.Default.GetInstance<ItemViewModel>();
page2ViewModel.SelectedItem = selectedItemViewModel;
_navigationService.Navigate(typeof(Page2),
selectedItemViewModel);
return null;
}
As you can see I'm using my Ioc to create get an instance of my Page2ViewModel and I then set the SelectedItem to the selectedItemViewModel.
Once it is set, I navigate to Page2 which is binded to my Page2ViewModel.
What I want to know is, is the above is ok to do? I've seen plenty of examples when dealing with passing object from one page to another is done by passing an Id for example and then I request the information from Page2, but why request it again when most of the information I need is already in my SelectedItemViewModel since it represents the tapped item in my list in Page1.
If it's not correct, what is the best way to go about this using MVVMLight?
Can you provide a sample? I've seen something about Messaging but I'm not sure how this would work as if I navigate to my page2, the Page2ViewModel will only be initiated when the page is created, so how can it receive a message? The way I have it above seems to initiate the Page2ViewModel and my Pag2 loads, it's re-using it and everything bind correctly but I'm not sure this is the correct way to go about it.
Any help would be appreciated.
Thanks.
In your Page2ViewModel, why not use
protected override void OnNavigatedTo(NavigationEventArgs e)
{
Page2SelectedItem = e.Parameter as ItemViewModel;
base.OnNavigatedTo(e);
}
It looks like you are packing that data in with your _navigationService.Navigate call already.
With that set up, what happens if you just change to:
private object ExecuteItempTapCommand(ItemViewModel selectedItemViewModel)
{
_navigationService.Navigate(typeof(Page2), selectedItemViewModel);
return null;
}
You can use the ViewModel to get it if you do some work before that.
Read this blog post by Marco Minerva called Calling ViewModel methods in response to Page navigation events using MVVM Light in WinRT
which explains how to react to OnNavigatedTo and OnNavigatedFrom in the ViewModel.
It's a very cool solution.

How to detect back button or forward button navigation in a silverlight navigation application

When a Page is navigated to in silverlight you can override this method.
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
}
The NavigationEventArgs has a NavigationMode enumeration which is defined as
public enum NavigationMode
{
New = 0,
Back = 1,
Forward = 2,
Refresh = 3,
}
But calling e.NavigationMode always throws a NotImplementedException
Is there a way in silverlight to detect a page is being navigated to because the user hit the forward/back browser button.
What I am trying to achieve is some kind of state that can be preserved when the user hits the back button.
For example assume you have a customer page which is showing a list of customers in a datagrid. The user can select a customer and there is a detail view which shows all the orders for that customer. Now within an order item you can click a hyperlink link that takes you to the shipping history of the order which is a separate page. When the user hits the back button I want to go back to the customers page and automatically select the customer he was viewing. Is this possible at all ?
I also tried out the fragment navigation feature
NavigationService.Navigate(new Uri("#currentcustomerid="
+ customer.Id.ToString(), UriKind.Relative));
when the customer selection changes but this adds too many items to the history when the user clicks various customers on the customer page.
EDIT
There is also an method you can override
protected override void OnNavigatingFrom(NavigatingCancelEventArgs e)
{
}
which is the same as handling the NavigationService.Navigating event as indicated by BugFinder's answer. In this method e.NavigationMode always returns New when when you hit the Back or Forward Button. The only time this method returns Back is when you explicitly call NavigationService.GoBack()
The
public enum NavigationMode
{
New = 0,
Back = 1,
Forward = 2,
Refresh = 3,
}
applies to the Navigating event..
if I do
_ns.Navigating += ns_Navigating;
void ns_Navigating(object sender, NavigatingCancelEventArgs e)
{
if (SecurityCheck(e.Uri.OriginalString)) return;
e.Cancel = true;
ShowError("You are not authorised to view this page");
}
I can see there that e.NavigationMode is set. You could do your test there?
I don't think there are any easy ways to do it out of the box, as far as I know.
What you are trying to achieve can be easily done using a framework I created at
http://ultimateframework.codeplex.com
What I have done is to mesh the silverlight navigation frame and prism navigation together, so you will need unity and prism and mvvm friendly.
What you want to achieve can be done using the framework in the following ways
1) Implement IsNavigationTarget and returns true --> which will keep the same instance when navigating back, therefore, keeping the selection/selected item.
2) Access the onnavigatedto's journal to track where you came from, say /item/1 was the previous stack, so you know back button has been pressed from item 1.
3) You can even implement your own back/forward/refresh within the custom control provided for achieving the same result (not in codeplex yet)
I actually use it for production code at work, and I created it, so please feel free to try it out. Note that the version on there is buggy, and I have yet to have time to release our latest build, but should you require it, I will update it for you :), just pm me.
Set a variable in the usercontrol containing the contentframe which indicates what customer is active.
Add a handler for the contentframe's Navigated event in the usercontrol. Use this to check the variable indicating what customer is active (if the variable is not null), and to select the customer.
This might be what you are looking for:
http://jakkaj.wordpress.com/2008/09/08/control-silverlight-by-using-browser-back-and-foward-buttons/

Hide elements in a web page whilst using a web-browser control for WP7

I am currently working on an app for WP7 for my university, and need a temporary solution to a problem. Now this solution is, that I will be loading a webpage using the web browser control for WP7. For example: http://m.iastate.edu/laundry/
Now as you see on the webpage, there are certain elements I want to hide, for example the back button. For now, what I have done to handle the back button is something like this:
private void webBrowser1_Navigating(object sender, NavigatingEventArgs e)
{
// Handle loading animations
// Handle what happens when the "back" button is pressed
Uri home = new Uri("http://m.iastate.edu/");
// The the current loading address is home
// Cancel the navigation, and go back to the
// apps home page.
if (e.Uri.Equals(home))
{
e.Cancel = true;
NavigationService.Navigate(new Uri("/MainPage.xaml", UriKind.Relative));
}
}
Now that works beautifully, except for the part that there is a back button on the hardware.
So my second option is to completely hide the back button ONLY on that page, and not its children. So not on http://m.iastate.edu/laundry/l/0
I am still debating on just parsing the data and displaying it in my own style, but I'm not sure if that's completely needed seeing how the data needs constant internet service and is already in a well-put format. Plus, I feel like that would be a waste of resources? Throw in your opinions on that too :)
Thanks!
You should inject a script in the page with InvokeScript.
Here is the kind of Javascript code you need to remove the back button:
// get the first child element of the header
var backButton = document.getElementsByTagName("header")[0].firstChild;
// check if it looks like a back button
if(backButton && backButton.innerText == "Back") {
// it looks like a back button, remove it
document.getElementsByTagName("header")[0].removeChild[backButton];
}
Call this script with InvokeScript:
webBrowser1.InvokeScript("eval", "(function() { "+ script +"}()");
Warning: IsScriptEnabled must be set to true on the web control
If the removal of the back button depends of the page, just test the navigating URI in C# and inject the script if neeeded.

Categories