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不再指向任何对象。主视图模型仍有引用,因此没有任何更改。您必须要求主视图模型从其集合中删除通知(可能通过回调方法(操作)是最好的,这样您就不必知道父视图模型)。

对不起,我不太确定您正在尝试做什么,什么不起作用,您能详细说明一下吗?在父窗口中,我有通知列表,我可以单击编辑选择通知。在编辑通知窗口中,我可以编辑通知或删除通知。编辑可以,但删除不能。