C# 在MVVM中的窗口之间传递DataContext
在主窗口上单击我的C# 在MVVM中的窗口之间传递DataContext,c#,wpf,mvvm,.net-3.5,datacontext,C#,Wpf,Mvvm,.net 3.5,Datacontext,在主窗口上单击我的 AddNoticeAboutWrongCity addNoticeAboutWrongCity = new AddNoticeAboutWrongCity(); addNoticeAboutWrongCity.DataContext = ((VerificationViewModule)this.DataContext).WrongCityNotice; addNoticeAboutWrongCity.ShowDialog(); 在弹出窗口中有许多文本框和两个按钮 删除对象
AddNoticeAboutWrongCity addNoticeAboutWrongCity = new AddNoticeAboutWrongCity();
addNoticeAboutWrongCity.DataContext = ((VerificationViewModule)this.DataContext).WrongCityNotice;
addNoticeAboutWrongCity.ShowDialog();
在弹出窗口中有许多文本框和两个按钮
删除对象:
this.DataContext=null
第二个选项“保存已编辑的通知”不可用,因为用户的每次更改都会影响主窗口上的datacontext,这是设计部门的要求:)
我不知道为什么第一个选项(它的“实现”不起作用
第二种解释:
在父窗口中,我有通知列表,我可以单击编辑选择通知 在编辑通知窗口中,我可以编辑通知或删除通知 Editing有效(在关闭EditNoticeWidow后,我在ParentWindow上看到更改的通知),但删除无效(通知仍在集合中-在控件上和此.DataContext中) 我的ViewModel:
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;
}
}
类验证视图模块
{
公共ObservableCollection ReporterNotices{get;set;}
公共报告通知其他通知
{
得到
{
return ReporterNotices.Where(n=>n.Type==ReporterNoticeType.Other).FirstOrDefault();
}
}
公共报告员重复通知
{
得到
{
return ReporterNotices.Where(n=>n.Type==ReporterNoticeType.Duplicate).FirstOrDefault();
}
}
公共报告人通知错误城市通知
{
得到
{
返回ReporterNotices.Where(n=>n.Type==ReporterNoticeType.ErrorCity).FirstOrDefault();
}
设置{if(值==null)
{
Remove(ReporterNotices.Where(n=>n.Type==ReporterNoticeType.ErrorCity).First());
}
其他的
{
if(ReporterNotices.Where(n=>n.Type==ReporterNoticeType.ErrorCity).FirstOrDefault()==null)//此类型通知的实例始终最多只有一个
{
报表注释。添加(值);
}
其他的
{
var c=ReporterNotices.Where(n=>n.Type==ReporterNoticeType.ErrorCity).First();
c=值;
}
}}
}
公共验证ViewModule()
{
ObservableCollection loadedReporterNotices=新的ObservableCollection();
loadedReporterNotices.Add(新的ReporterNotice(){Content=“Dublic”,Type=ReporterNoticeType.ErrorCity});
loadedReporterNotices.Add(new ReporterNotice(){Content=“Hilton”,Type=ReporterNoticeType.Duplicate});
loadedReporterNotices.Add(new ReporterNotice(){Content=“Other notice”,Type=ReporterNoticeType.Other});
ReporterNotices=loadedReporterNotices;
}
}
您可以尝试以下操作。实现中介以显示窗口,并确保对主窗口和编辑窗口的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);
}
//此viewmodel位于主windows datacontext上
公共类ParentViewModel
{
私有只读IWindowMediator\u mediator;
公共ParentViewModel(IWindowMediator中介)
{
_调解人=调解人;
}
public observeCollection通知{get;private set;}//绑定到xaml中的列表
公告(公告)
{
//使用中介模式打开窗口,而不是直接打开新窗口
_mediator.Open(neweditNoticeViewModel(notice,DeleteNotice));
}
私人作废通知(通知通知)
{
//这将从主窗口列表中删除它
通知。删除(通知);
}
}
//EditNoticeWindow的视图模型
公共类EditNoticeViewModel
{
public EditNoticeViewModel(操作deleteCallback,通知通知)
{
模型=通知;
DeleteCommand=newdelegateCommand((a)=>deleteCallback(Model));
}
//在xaml中绑定到按钮的命令
DelegateCommand DeleteCommand{get;private set;}
//绑定到xaml中的控件。
公告模型{get;private set;}
}
//这是一个基本界面,您可以根据需要进行详细说明
//但它处理窗口的打开。附加视图模型
//指向窗口的数据上下文。
公共接口iWindows编辑器
{
空洞开放(T型);
}
根据具体实现,您可能希望在按下“删除”按钮时关闭视图。您可以通过实现类似于WorkspaceViewModel所述的操作来实现此操作。为什么不在viewModel中包装错误的CityNotice,实现IReporterNotice并引用父视图模型和delete方法:
//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);
}
public void Delete() { _parentvm.Delete(_wrongCityNotice); }
您可以将此包装器用作DataContext。您正在尝试销毁DataContext。C#不是这样工作的。将对象引用设置为null不会删除该对象,它只会删除对该对象的引用。(当不再有任何对象引用时,它会被垃圾收集,但您不能直接销毁对象)
DataContext=null仅表示本地DataContext不再指向任何对象。主视图模型仍有引用,因此没有任何更改。您必须要求主视图模型从其集合中删除通知(可能通过回调方法(操作)是最好的,这样您就不必知道父视图模型)。对不起,我不太确定您正在尝试做什么,什么不起作用,您能详细说明一下吗?在父窗口中,我有通知列表,我可以单击编辑选择通知。在编辑通知窗口中,我可以编辑通知或删除通知。编辑可以,但删除不能。