在MVVM中的窗口之间传递DataContext

时间:2010-07-05 12:53:05

标签: c# wpf mvvm .net-3.5 datacontext

在主窗口上点击我有

AddNoticeAboutWrongCity addNoticeAboutWrongCity = new AddNoticeAboutWrongCity();
addNoticeAboutWrongCity.DataContext = ((VerificationViewModule)this.DataContext).WrongCityNotice;
addNoticeAboutWrongCity.ShowDialog();

在弹出窗口中有很多文本框和两个按钮

删除对象:

this.DataContext = null;

第二个选项“保存已编辑的通知”是不可用的,因为主窗口上的用户感情datacontext的每次更改,这都是设计部门的要求:)

我不知道为什么第一个选项(它的“实现”不起作用。

第二个解释:

在ParentWindow上我有通知列表,我可以点击EditSelectedNotice。

在EditNoticeWindow上,我可以编辑通知或删除通知。

Editinig有效(关闭EditNoticeWindow后,我在ParentWindow上看到更改通知),但删除没有(通知仍然在集合中 - 在控件上和在this.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;
        }


    }

3 个答案:

答案 0 :(得分:0)

您可以尝试以下操作。实现介体以显示窗口,并确保为主窗口和编辑窗口使用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);
}

根据实现,您可能希望在按下删除按钮时关闭视图。您可以通过实现类似于WorkspaceViewModel

所描述的here之类的内容来实现此目的

答案 1 :(得分:0)

为什么不在实现IReporterNotice的viewModel中包装WrongCityNotice并引用父视图模型和Delete方法:

public void Delete() { _parentvm.Delete(_wrongCityNotice); }

您可以将此包装器用作DataContext。

答案 2 :(得分:0)

您正在尝试销毁DataContext。 C#无法正常工作。将对象引用设置为null不会删除该对象,它只会删除对它的引用。 (当没有任何东西引用一个对象时,它会被垃圾收集,但是你不能直接销毁一个对象。)

DataContext = null仅表示您的DataContext本地不再指向任何对象。主视图模型仍有参考,因此没有任何变化。你必须要求主视图模型从它的集合中删除通知(可能通过回调方法(Action)是最好的,这样你就不必知道父视图模型了。)