从子窗口刷新 WPF 页面

Posted

技术标签:

【中文标题】从子窗口刷新 WPF 页面【英文标题】:Refresh a WPF page from a child window 【发布时间】:2013-08-12 10:01:56 【问题描述】:

C# WPF 我有一个窗口使用this.WorkingFrame.Navigate(Page1); 托管页面 现在在第 1 页我有一个listview。在第 1 页上,您可以双击 listview 中的项目以打开一个新窗口(第 2 页)以编辑该项目。一旦项目被编辑,它就会被保存到datacontext。现在我遇到的问题是,一旦 Page2 关闭,listview 就不会更新。基本上我必须离开页面并返回它以显示更改。有没有办法从 Page2 刷新 Page1 以显示所做的更改? 这是我的代码

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

【问题讨论】:

如果你正确使用它,你应该考虑使用一个可观察的集合,你的 ui 将自动反映变化。即使在对话框关闭之前,您的更改也会反映在第 1 页中 【参考方案1】:

这个问题更加普遍 - 视图可能非常复杂,并且在某处修改的数据应该在其他地方失效/刷新。假设您不仅有两个处于父子关系的窗口,而且还有一个复杂的嵌套视图,带有选项卡或动态浮动窗口。显然,这不仅仅是“从孩子刷新父母”。

那么可能的方法是什么?答案是:messagingpublish-subsribe 模式。您需要一个事件聚合器,例如 Prism4 中就有一个。聚合器允许您的视图订阅消息并发布消息。

在您的案例中,消息传递架构很简单。你需要一个事件,比如

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; 

然后您的父视图订阅该事件,您的子视图发布该事件,在事件参数中传递更新后的实体。

一旦您有了在应用程序的不同区域之间传递消息的想法,您的代码就会变得不那么耦合,您就会停止思考“这两个类之间是否存在联系?也许是父子关系?”而是您开始思考“应该从那里流向那里的信息是什么?”。

编辑短期解决方案是:

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

【讨论】:

这听起来对我将来想做的事情很有帮助,但是由于我是 C# 和 WPF 的新手,我不确定代码会去哪里以及“JustAnything”是什么" 应该设置为,你能提供一个使用我的代码的例子吗? 第一个属性是一个示例 - 您传递已更新的实体。在订阅者方面,您在收到通知后有两个选择:要么刷新整个视图(重新绑定列表),要么只刷新在通知中传递的元素。 看这个,你的建议是复杂的方式来满足我的需要。我只需要 page2 在 page1 关闭时刷新它 Page2 的构造函数接受Page1 的实例,以便对父级的引用在子级中可用。然后,只需从子级调用父级的公共方法。就这么简单,但它无处可去,从某种意义上说,您迟早会需要消息传递。 查看上面的编辑,我添加了它,但是当它调用 LoadLV 时,我得到一个“对象引用未设置为对象的实例”。我把它放错地方了吗?我误会了吗?这些电话到底去哪儿了?【参考方案2】:
MainWindow mainWindow = new MainWindow();

mainWindow.Closed += (s, eventarg) =>

    // Your method to update parent window
;

mainWindow.Show();

【讨论】:

以上是关于从子窗口刷新 WPF 页面的主要内容,如果未能解决你的问题,请参考以下文章

窗口最小化时如何强制刷新缩略图? (C#WPF)

在wpf或winform关闭子窗口或对子窗口进行某个操作后刷新父窗口

WPF关闭子窗口时刷新父页面列表数据,WPF窗体间传参

WPF MVVM里,当用户在新窗口执行完后如何返回原窗口,并刷新

关闭jQUERY中的弹出窗口后如何刷新父页面? [复制]

请教winform刷新问题