如何在Frame中获取父页面并向其传递对象?
解决WPF中Frame向父页面传递对象的问题
Frame的Parent属性返回null是因为WPF的Frame作为导航容器,其内部加载的页面处于独立的导航上下文,无法直接通过Parent获取父页面。下面提供两种可靠的解决方案:
方案一:自定义事件(适合代码后置场景)
通过在Frame页面中定义自定义事件,将数据以事件参数的形式传递给父页面,完全避免直接依赖父页面引用。
步骤1:在Frame承载的页面中定义事件及参数
// 自定义事件参数,用于携带要传递的数据对象 public class ItemAddedEventArgs : EventArgs { public YourDataModel NewItem { get; set; } } // 在Frame页面的类中声明事件 public event EventHandler<ItemAddedEventArgs> ItemAdded;
步骤2:触发事件(添加按钮点击时)
private void addBtnClick(object sender, RoutedEventArgs e) { // 收集输入数据,构造业务对象 var newItem = new YourDataModel { Desc = inputDesc.Text, Time = $"{inputHours.Text}:{inputMins.Text}", Date = DateTime.Now.ToString("yyyy-MM-dd") }; // 触发事件,传递对象 ItemAdded?.Invoke(this, new ItemAddedEventArgs { NewItem = newItem }); }
步骤3:父页面订阅事件
在父页面切换Frame内容时,订阅子页面的事件:
private void Form1Button_Click(object sender, RoutedEventArgs e) { var form1Page = new Form1Page(); // 订阅子页面的事件 form1Page.ItemAdded += OnItemAdded; inputFrame.Navigate(form1Page); } private void OnItemAdded(object sender, ItemAddedEventArgs e) { // 将传递的对象添加到ListView的数据源 yourItemsCollection.Add(e.NewItem); }
方案二:MVVM模式(推荐,解耦更彻底)
通过共享数据源或消息传递实现数据交互,完全符合WPF的MVVM设计思想。
示例:使用消息传递(以MvvmLight为例)
子ViewModel发送消息
private ICommand _addCommand; public ICommand AddCommand => _addCommand ??= new RelayCommand(() => { var newItem = new YourDataModel { Desc = InputDesc, Time = $"{InputHours}:{InputMins}", Date = DateTime.Now.ToString("yyyy-MM-dd") }; // 发送消息传递对象 Messenger.Default.Send(newItem); });
父ViewModel订阅消息
public class ParentViewModel { public ObservableCollection<YourDataModel> Items { get; } public ParentViewModel() { Items = new ObservableCollection<YourDataModel>(); // 订阅消息,接收子ViewModel传递的对象 Messenger.Default.Register<YourDataModel>(this, item => { Items.Add(item); }); } }
之后只需将父页面的ListView绑定到ParentViewModel.Items,子页面的输入控件绑定到子ViewModel的对应属性即可。
内容的提问来源于stack exchange,提问作者Dave
相关产品推荐
相关产品推荐

