pfinferno pfinferno - 4 years ago 95
C# Question

Get property values from another view model when its window closes

I have a view model which has a command in it that shows a new window (that has it's own view model). The new window's view model has various properties, and when I close the new window, I want to pass those properties back to the first view model that called it.

I'm breaking the MVVM pattern here since it just seemed quicker and easier to show the new window with

ShowDialog()
. Here's an example of my code:

MainViewModel:

//Note: The OnPropertyChanged and CanExecute functions are implemented

//method via command to show a new window
private void ShowSYOWindow(object parameter)
{
SYOWindow syo = new SYOWindow();
syo.ShowDialog();
}


New window's view model:

class SYOWindowViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;

private DateTime _timeStart;
public DateTime TimeStart
{
get { return _timeStart; }
set { _timeStart = value; OnPropertyChanged("TimeStart"); }
}

private DateTime _timeStart2;
public DateTime TimeStart2
{
get { return _timeStart2; }
set { _timeStart2 = value; OnPropertyChanged("TimeStart2"); }
}

// Create the OnPropertyChanged method to raise the event
protected void OnPropertyChanged(string name)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
}


So after I open the new window with 'syo.ShowDialog()' from the MainViewModel, and I set some properties in the SYOWindowViewModel for the syo Window, I want to return those properties to the MainViewModel. I can't figure out what the 'proper' and cleanest way to do this is. I've read that I can cast the DataContext and then get the values that way, but that seems kind of wrong. But maybe the only way since I broke the MVVM using the showdialog.

Answer Source

ShowDialog() blocks, so you can just have the parent take stuff from the child's viewmodel after ShowDialog() exits:

private void ShowSYOWindow(object parameter)
{
    SYOWindow syo = new SYOWindow();
    syo.ShowDialog();

    var vm = (SYOWindowViewModel)syo.DataContext;

    this.Foo = vm.Foo;
}

You probably called SYOWindow's viewmodel something else, but you get the idea.

You can simplify the code a bit if you give SYOWindow a ViewModel property:

public partial class SYOWindow
{
    //  ...stuff

    public SYOWindowViewModel ViewModel => (SYOWindowViewModel)DataContext;

    //  ...more stuff
 }

Then the parent can just do like so:

private void ShowSYOWindow(object parameter)
{
    SYOWindow syo = new SYOWindow();

    syo.ShowDialog();

    this.Foo = syo.ViewModel.Foo;
}

And if SYOWindow uses its DialogResult property, you can do stuff like this:

private void ShowSYOWindow(object parameter)
{
    SYOWindow syo = new SYOWindow();

    if (syo.ShowDialog().GetValueOrDefault())
    {
        this.Foo = syo.ViewModel.Foo;
    }
}
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download