【问题标题】:Passing DataContext between windows in MVVM在 MVVM 中的窗口之间传递 DataContext
【发布时间】: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 我可以编辑通知或删除通知。编辑有效,但删除无效。

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


【解决方案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),这样您就不必了解父视图模型)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-10-12
        • 1970-01-01
        相关资源
        最近更新 更多