在 MVVM 中的窗口之间传递 DataContext
Posted
技术标签:
【中文标题】在 MVVM 中的窗口之间传递 DataContext【英文标题】:Passing DataContext between windows in MVVM 【发布时间】:2011-03-11 21:51:16 【问题描述】:在主窗口上点击我有
AddNoticeAboutWrongCity addNoticeAboutWrongCity = new AddNoticeAboutWrongCity();
addNoticeAboutWrongCity.DataContext = ((VerificationViewModule)this.DataContext).WrongCityNotice;
addNoticeAboutWrongCity.ShowDialog();
在弹出窗口有很多文本框和两个按钮
删除对象:
this.DataContext = null;
第二个选项“保存编辑的通知”不可用,因为主窗口上的用户情感数据上下文的每次更改,这是设计部门的要求:)
我不知道为什么第一个选项(它的“实施”不起作用。
第二个解释:
在 ParentWindow 我有通知列表,我可以单击 EditSelectedNotice。
在 EditNoticeWindow 我可以编辑通知或删除通知。
Editinig 有效(关闭 EditNoticeWindow 后,我在 ParentWindow 上看到更改的通知),但删除没有(通知仍在收集中 - 在控件和 this.DataContext 中)
我的视图模型:
class VerificationViewModule
public ObservableCollection<ReporterNotice> ReporterNotices get; set;
public ReporterNotice OtherNotice
get
return ReporterNotices.Where(n => n.Type == ReporterNoticeType.Other).FirstOrDefault();
public ReporterNotice DuplicateNotice
get
return ReporterNotices.Where(n => n.Type == ReporterNoticeType.Duplicate).FirstOrDefault();
public ReporterNotice WrongCityNotice
get
return ReporterNotices.Where(n => n.Type == ReporterNoticeType.WrongCity).FirstOrDefault();
set if(value==null)
ReporterNotices.Remove(ReporterNotices.Where(n => n.Type == ReporterNoticeType.WrongCity).First());
else
if (ReporterNotices.Where(n => n.Type == ReporterNoticeType.WrongCity).FirstOrDefault()==null)//there is always only max one instance of this type of notice
ReporterNotices.Add(value);
else
var c = ReporterNotices.Where(n => n.Type == ReporterNoticeType.WrongCity).First();
c = value;
public VerificationViewModule()
ObservableCollection<ReporterNotice> loadedReporterNotices = new ObservableCollection<ReporterNotice>();
loadedReporterNotices.Add(new ReporterNotice() Content = "Dublic", Type = ReporterNoticeType.WrongCity );
loadedReporterNotices.Add(new ReporterNotice() Content = "Hilton", Type = ReporterNoticeType.Duplicate );
loadedReporterNotices.Add(new ReporterNotice() Content = "Another notice", Type = ReporterNoticeType.Other );
ReporterNotices = loadedReporterNotices;
【问题讨论】:
抱歉,我不太确定你想做什么,什么不起作用,你能详细说明一下吗? 在 ParentWindow 我有通知列表,我可以单击 EditSelectedNotice。在 EditNoticeWindow 我可以编辑通知或删除通知。编辑有效,但删除无效。 【参考方案1】:您可以尝试以下方法。实现中介以显示窗口,并确保您对主窗口和编辑窗口的 DataContext 使用视图模型。告诉主视图模型对象正在被删除是很重要的。这是通过回调并通过 EditNoticeViewModel 上的命令路由来完成的
//This viewmodel is on the main windows datacontext
public class ParentViewModel
private readonly IWindowMediator _mediator;
public ParentViewModel(IWindowMediator mediator)
_mediator = mediator;
public ObservableCollection<Notice> Notices get; private set; //bound to list in xaml
public void OpenNotice(Notice notice)
//open the window using the Mediator pattern rather than a new window directly
_mediator.Open(new EditNoticeViewModel(notice, DeleteNotice));
private void DeleteNotice(Notice notice)
//This will remove it from the main window list
Notices.Remove(notice);
//view model for EditNoticeWindow
public class EditNoticeViewModel
public EditNoticeViewModel(Action<Notice> deleteCallback, Notice notice)
Model = notice;
DeleteCommand = new DelegateCommand((a) => deleteCallback(Model));
//Bind in xaml to the Command of a button
DelegateCommand DeleteCommand get; private set;
//bound to the controls in the xaml.
public Notice Model get; private set;
//This is a basic interface, you can elaborate as needed
//but it handles the opening of windows. Attach the view model
//to the data context of the window.
public interface IWindowMediator
void Open<T>(T viewModel);
根据实现,您可能希望在按下删除按钮时关闭视图。您可以通过实现类似 here 中描述的关于 WorkspaceViewModel 的方法来做到这一点
【讨论】:
【参考方案2】:为什么不将 WrongCityNotice 包装在实现 IReporterNotice 并引用父视图模型和 Delete 方法的视图模型中:
public void Delete() _parentvm.Delete(_wrongCityNotice);
您可以将此包装器用作 DataContext。
【讨论】:
【参考方案3】:您正试图破坏 DataContext。 C# 不能那样工作。将对象引用设置为 null 不会删除该对象,它只会删除对它的引用。 (当不再引用一个对象时,它会被垃圾收集,但你不能直接销毁一个对象)。
DataContext = null 仅表示您的 DataContext 在本地不再指向任何对象。主视图模型仍然有一个参考,但是那里没有任何变化。您必须要求主视图模型从其集合中删除通知(最好通过回调方法 (Action),这样您就不必了解父视图模型)。
【讨论】:
以上是关于在 MVVM 中的窗口之间传递 DataContext的主要内容,如果未能解决你的问题,请参考以下文章
从Caliburn.Micro,WPF,MVVM中的另一个窗口获取信息