Passing a DataContext between windows in MVVM

In the main onClick window I have

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

There are many text and two buttons in the popup

Delete item:

this.DataContext = null;

And the second option is “Save edited notification”, which cannot be used, since every change in the user attachment of the datacontext is in the main window, and this is required from the design department :)

I do not know why the first option (this "implementation" does not work.

The second explanation:

In ParentWindow, I have a list of notifications and I can click EditSelectedNotice.

In EditNoticeWindow, I can edit the notification or delete the notification.

Editing works (after closing EditNoticeWindow I see a modified notification in ParentWindow), but the deletion fails (the notification is still in the collection - on the control and in this .DataContext)

My 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; } } 
+4
source share
3 answers

You can try the following. Implement a mediator to display windows and make sure that you are using presentation models for the DataContext for both main and window editing. It is important to indicate the basic representation model that the object is deleted. This is done using callback and routing, which using the EditNoticeViewModel command

  //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); } 

Depending on the implementation, you may close the view when you click the delete button. You can do this by implementing something like the one described here regarding the WorkspaceViewModel

0
source

Why don't you wrap WrongCityNotice in a viewModel that implements IReporterNotice and has a link to the parent view model and the Delete method:

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

You can use this shell as a DataContext.

0
source

You are trying to destroy a DataContext. C # does not work. Setting the reference to the object to null does not delete the object, but only removes the reference to it. (When nothing refers to the object anymore, it gets garbage, but you cannot destroy the object directly).

DataContext = null means that locally your DataContext is no longer pointing to any object. The main review model still has a link, so nothing changes there. You will need to ask the main view model to remove the notification from this collection (perhaps using the callback method (Action) is best, so you do not need to know the model of the parent view).

0
source

Source: https://habr.com/ru/post/1314734/


All Articles