Typically, one pops the current page using this from the NavigationStack:
Navigation.PopAsync( true );
How to I use Navigation to redraw the page just before the current page?
Background: The current page changed something that need to get re-presented in the one but last page.
I'm assuming that the data model that you are using is not observable/bindable and thus the page is not "auto-updated"...
You could use MessagingCenter to publish a "Refresh Event" to avoid coupling the two Pages with events...
In your MainPage:
MessagingCenter.Subscribe<MainPage> (this, "RefreshMainPage", (sender) => {
// Call your main page refresh method
});
In your Second Page:
MessagingCenter.Send<MainPage> (this, "RefreshMainPage");
Navigation.PopAsync( true );
https://developer.xamarin.com/guides/xamarin-forms/messaging-center/
As #SushiHangover mentioned, MessagingCenter is a good option.
Another way would be to subscribe to Page2's OnDisappearing() event from page1 and do something to the Page1 UI/data like so:
Edit: The old way I answered this question (see changelog) does work but I have since modified how I do it, after seeing others' examples, to prevent memory leaks. It is better to unsubscribe from the Disappearing event after it has been used. If you plan to use it again then you can just resubscribe to it before running PushAsync() again on your Page2 instance:
private async void OnGoToPage2Clicked(object sender, EventArgs args) {
Page2 page2 = new Page2();
page2.Disappearing += OnPage2Disappearing;
await Navigation.PushAsync(page2);
}
private async void OnPage2Disappearing(object sender, EventArgs eventArgs) {
await _viewModel.RefreshPage1Data(); //Or how ever you need to refresh the data
((Page2)sender).Disappearing -= OnPage2Disappearing; //Unsubscribe from the event to allow the GC to collect the page and prevent memory leaks
}
Here is what I had to do to get hvaughan3's solution to work for me:
private async void OnGoToPage2Clicked(object sender, EventArgs args) {
Page2 page2 = new Page2();
page2.Disappearing += Page2_Disappearing;
await Navigation.PushAsync(page2);
}
private void Page2_Disappearing(object sender, EventArgs e) {
this.Refresh(); // what your refresh or init function is.
}
When I saw that solution I liked that as the option for me since I'm real heavy into using events to solve most of my problems. Thanks hvaughan3!
Related
I use TimeSpanPicker in my app. When I pick my time from the timer, it will go back to the initial page automatically (lets say setTime.xaml page). However, I want to change the navigation to another page rather than the setTime.xaml page.
enter code here
>> setTime.Xaml.cs Page
TimeSpanPicker tsp = new TimeSpanPicker();
tsp.ValueChanged += change_Value();
>> Event Handler
private void change_Value(object sender, RoutedPropertyChanedEventArgs <TimeSPan> e)
{
//do something
}
How can I change its navigation to another page?
Add a event for ValueChanged. Write the event handler like this:
private void TimePicker_ValueChanged(object sender, DateTimeValueChangedEventArgs e)
{
NavigationService.Navigate(new Uri("/MainPage.xaml", UriKind.Relative));
}
I have 2 pages in my application, A and B.
If I'm navigation from the outside of the application to A, I want to display a message box. If I'm navigation from B to A, I don't want to display anything.
Is there any way to identify in A the page which initiated navigation? i.e in A.Loaded (or any other event) I need something like
if(pageFromWhichIAmComingFrom == B)
OnNavigatedTo, OnNavigationFrom and OnNavigatedFrom don't seem to help me.
You could use the PhoneApplicationService class to store information about what page you were on last. For example, use OnNavigatedFrom on Page A:
void OnNavigatedFrom(object sender, Eventargs e)
{
PhoneApplicationService.Current.State["LastPage"] = "PageA";
}
And then check for that on the next page:
void OnNavigatedTo(object sender, Eventargs e)
{
if(PhoneApplicationService.Current.State["LastPage"].ToString() == "PageA")
{
// came from page A
}
else
{
// came from a different page
}
}
Hope this helps!
UPDATE:
One more thing I just saw that might be worth trying is using the NavigationService.BackStack property. I haven't tried this, but it seems like it should work. In your OnNavigatedTo event handler, you should be able to get the last entry from the stack to see your last page. This would be simpler and wouldn't require you to set any properties manually. Example:
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
base.OnNavigatedTo(e);
var lastPage = NavigationService.BackStack.FirstOrDefault();
}
Found here.
I need to send a click event to refreshToolStripMenuItem from another form. Here is what I have, for some reason it doesn't work. Help please.
Menu item click:
public void refreshToolStripMenuItem_Click(object sender, EventArgs e)
{
noteslist.Items.Clear();
idlist.Items.Clear();
setnotes();
}
Code used to send event:
frmnotes notes = new frmnotes();
notes.refreshToolStripMenuItem_Click(this, e);
this.Close();
Dont call the event itself.
It's bad code.
Put the create an own protected void updateMyList() Method.
internal void updateMyList()
{
noteslist.Items.Clear();
idlist.Items.Clear();
setnotes();
}
Then call the update-method from within your event.
private void refreshToolStripMenuItem_Click(object sender, EventArgs e)
{
updateMyList();
}
Then simply call the update-method from your form:
frmnotes notes = new frmnotes();
notes.updateMyList();
this.Close();
Btw.: Set the modifier of your Click events i.e. refreshToolStripMenuItem_Click to private.
You never should call them from outside the form.
Take a look at the MVC pattern for more info. It really helps.
I have a Main page that contains a listBox.
When a user selects a profile form the list box, this opens up a child window called pWindow.
This window as the option to delete the current profile via a hyperlink button that opens up a another confirmation window called dprofile.
My question being is it possible that once a user has confirmed to delete the current profile they are in, and confirmed it in the button click on dProfile, how can I update the listBox in the first Main page so that the list no longer contains the deleted profile (which it is not doing at present.
In the dProfile window I have created an event -
public event EventHandler SubmitClicked;
Where in the OK button click I have-
private void OKButton_Click(object sender, RoutedEventArgs e)
{
if (SubmitClicked != null)
{
SubmitClicked(this, new EventArgs());
}
}
So on the Main page I have added-
private void deleteProfile_SubmitClicked(object sender, EventArgs e)
{
WebService.Service1SoapClient client = new WebService.Service1SoapClient();
listBox1.Items.Clear();
client.profileListCompleted += new EventHandler<profileListCompletedEventArgs>(client_profileListCompleted);
client.profileListAsync(ID);
}
I thought this may have updated the listBox as it was confirmed in the dProfile form however when the form closes, the listBox stays the same and I have to manually refresh the webpage to see the update. How can I do this?
If I understood it correctly then you have three pages. Main, pWindow and dProfile. Earlier you were trying to close pWindwow from dProfile and that was working properly. Now you want to refresh the listBox1 on Main Page.
To achieve that you may follow a similar strategy. You are probably opening pWindow from Main page with something on the following line
pWindow pWin = new pWindow();
pWin.Show();
Now you may define a new event in pWindow class.
public event EventHandler pWindowRefeshListBox;
Then in your event handler for deleteProfile_SubmitClicked you may raise the event to refresh listbox1, something on the following line:
private void deleteProfile_SubmitClicked(object sender, EventArgs e)
{
if(pWindowRefreshListBox != null)
pWindowRefreshListBox(this, new EventArgs());
this.Close();
}
Then in your main page register the event against pWin object, which you defined earlier.
pWin.pWindowRefreshListBox += new new EventHandler(pWindow_pWindowRefreshListBox);
Then define the event in Main page.
private void pWindow_pWindowRefreshListBox(object sender, EventArgs e)
{
listBox1.Items.Clear();
}
This should refresh the listbox. I haven't test the code or the syntax. So you may check it
before implementing.
EDIT
you may define the event in dProfile as static
public static event EventHandler SubmitClicked;
Then you will be able to register it in Main and pWindow against Class Name
dProfile.SubmitClicked += new ..............
Then implement it accordingly, in pWindow, close the window and in main refresh listbox
EDIT:
You may create instance of deleteProfile on the main page register the following in your main
deleteProfile.SubmitClicked += new EventHandler(deleteProfile _SubmitClicked)
this should work
I have a Windows Forms Link Label, "Refresh", that refreshes the display.
In another part of my code, part of a separate windows form, I have a dialog that changes the data loaded into the display in the first place. After executing this other code, pressing "Refresh" updates the data correctly.
Is there a simple way for the dialog menu to "click" the "refresh" Link Label after it has finished altering the data?
Using Visual Studio 2008.
For button is really simple, just use:
button.PerformClick()
Anyway, I'd prefer to do something like:
private void button_Click(object sender, EventArgs e)
{
DoRefresh();
}
public void DoRefresh()
{
// refreshing code
}
and call DoRefresh() instead of PerformClick()
EDIT (according to OP changes):
You can still use my second solution, that is far preferable:
private void linkLabel_Click(object sender, EventArgs e)
{
DoRefresh();
}
public void DoRefresh()
{
// refreshing code
}
And from outside the form, you can call DoRefresh() as it is marked public.
But, if you really need to programmatically generate a click, just look at Yuriy-Faktorovich's Answer
You could call the PerformClick method. But Generally it is better to have the Click event of the button call a Refresh method you write. And the menu call that method as well. Otherwise your menu depends on the button being there.
Edit:
A LinkLabel implements the IButtonControl explicitly. So you could use:
((IButtonControl)button).PerformClick();
you can use a method to refrech display, the bouton_click and the dialogBox call this method
public void refrechDate()
{
}
private void button_click(...)
{
refrechData();
}
private void MyMethod()
{
// ...
// calling refresh
this.button1_Click(this.button1, EventArgs.Empty);
// ...
}
private void button1_Click(object sender, EventArgs e)
{
// refresh code
}