从子窗口刷新 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】:这个问题更加普遍 - 视图可能非常复杂,并且在某处修改的数据应该在其他地方失效/刷新。假设您不仅有两个处于父子关系的窗口,而且还有一个复杂的嵌套视图,带有选项卡或动态浮动窗口。显然,这不仅仅是“从孩子刷新父母”。
那么可能的方法是什么?答案是:messaging,publish-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 页面的主要内容,如果未能解决你的问题,请参考以下文章
在wpf或winform关闭子窗口或对子窗口进行某个操作后刷新父窗口