Передача DataContext между окнами в MVVM - PullRequest
4 голосов
/ 05 июля 2010

В главном окне onClick у меня есть

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

Во всплывающем окне много текстовых полей и две кнопки

Удалить объект:

this.DataContext = null;

И второй вариант «Сохранить отредактированное уведомление», который не может быть использован, потому что каждое изменение данных о привязанности пользователя в главном окне, и это требование от отдела дизайна:)

Я незнать, почему первый вариант (это «реализация» не работает.

Второе объяснение:

В ParentWindow у меня есть список уведомлений, и я могу нажать EditSelectedNotice.

Вкл.EditNoticeWindow, я могу редактировать Notice или удалять Notice.

Editinig работает (После закрытия EditNoticeWindow я вижу измененное уведомление в ParentWindow), но удаление нет (Notice все еще находится в коллекции - на элементе управления и в этом.)

Моя 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 голосов
/ 14 июля 2010

Почему бы вам не обернуть WrongCityNotice в модель представления, реализующую IReporterNotice и имеющую ссылку на родительскую модель представления и метод Delete:

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

Вы можете использовать эту оболочку как DataContext.

0 голосов
/ 14 декабря 2010

Вы пытаетесь уничтожить DataContext. C # не работает таким образом. Установка нулевой ссылки на объект не удаляет объект, а только удаляет ссылку на него. (Когда ничто больше не ссылается на объект, он получает мусор, но вы не можете уничтожить объект напрямую).

DataContext = только null означает, что локально ваш DataContext больше не указывает ни на какой объект. Модель основного вида по-прежнему имеет ссылку, поэтому ничего не меняется. Вам нужно будет попросить модель основного представления удалить уведомление из его коллекции (возможно, лучше использовать метод обратного вызова (Action), поэтому вам не нужно знать о модели родительского представления).

0 голосов
/ 08 июля 2010

Вы можете попробовать следующее.Реализуйте посредник для отображения окон и убедитесь, что вы используете модели представления для 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

...