Joe K
Joe K

Reputation: 241

Refresh a WPF page from a child window

In C# WPF I have a window which hosts a page using this.WorkingFrame.Navigate(Page1); Now on Page 1 I have a listview. On page 1 you can double click an item in the listview to open a new window (Page2) to edit the item. Once the item is edited it is saved in to the datacontext. Now the issue I am having, is once Page2 is closed, the listview is not updated. Basically I have to navigate away from the page and back to it to get it to show the changes. Is there a way to refresh Page1 from Page2 to show the changes made? Here is my code

public partial class Page1 : Page
{
    public Page1()
    {            
        InitializeComponent();
    }
    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        //initiates the method to load data into the list view
        LoadLV();
    }
    //Loads data into the list view object
    public void LoadLV()
    {

        auroraDataEntities = new AuroraDataEntities();
        Data data = new Data();
        ObjectQuery<Inventory> inventories = auroraDataEntities.Inventories;
        //Returns only objects with a quantity greater than 0, so it won't show anything you are out of
        var fillList = from q in inventories
                       where q.Qty > 0
                       select q;
        ingListLV.ItemsSource = fillList.ToList();

     }
    //Method to open what I want to be the child window basically a popup Dialog box
    private void Open_Page2(object sender, RoutedEventArgs e)
    {
        Page2 openPage2 = new Page2();
        openPage2.Show();

    }
}

    //This is the code for Page 2
public partial class Page2 : Window
{    


     public Page2()
    {            
        InitializeComponent();
        //ADDED a reference to Page1 in the constructor
        Page1 page1;
    }

    //Method when i click the close button on the page
    private void Close_Button(object sender, RoutedEventArgs e)
    {
    //In here is the code that I want to use to refresh the listview on page 1
            //ADDED the call to the public method LoadLV on page 1
            page1.LoadLV()              
    }
}

Upvotes: 0

Views: 4891

Answers (2)

hasanadiguzel
hasanadiguzel

Reputation: 14

MainWindow mainWindow = new MainWindow();

mainWindow.Closed += (s, eventarg) =>
{
    // Your method to update parent window
};

mainWindow.Show();

Upvotes: -1

Wiktor Zychla
Wiktor Zychla

Reputation: 48279

The issue is even more general - views could possibly be arbitrarily complicated and the data modified somewhere should be invalidated/refreshed somewhere else. Suppose you don't just have two windows in a parent-child relation but a complicated nested views, with tabs or dynamic floating windows. Apparently, this is not just about "refresh parent from child".

So what is the possible approach to this? The answer is: messaging, the publish-subsribe pattern. You need an Event Aggregator, you have one in Prism4 for example. The aggregator lets your views subscribe to messages and publish messages.

The messaging architecture in your case is simple. You need an event, something like

public class BusinessEntityUpdatedEvent : CompositePresentationEvent
{
   public object Entity { get; set; }

   //or

   // if your entities share a common base class
   public EntityBase Entity { get; set; }   

   //or

   public justAnything ofAnyType { get; set; }
   public orEvenMore ofAnotherType { get; set; }
}

and then your parent view subscribes to that event and your child view publishes the event, passing the updated entity inside event parameters.

Once you get the idea of messaging between different areas of your application, your code becomes much less coupled, you stop to think in terms of "is there a connection between these two classes? a parent-child relation perhaps?" but rather you start to think in terms of "what message should flow from there to there?".

Edit A short term solution would be:

public class Page1
{ 
   private void OpenPage2()
   {
      Page2 p = new Page2( this );
      p.Show();
   }

   public void LoadLv() ...
}

public class Page2
{
   private Page1 page1;
   public Page2( Page1 page1 )
   {
      this.page1 = page1;
   }

   public void CloseButton()
   {
      this.page1.LoadLV();
   }
}

Upvotes: 1

Related Questions