0
votes

I have made quite a bit of progress on my first MVVM WPF application, the issue I am now having is I have a Window that has a viewmodel.
This window has a button which opens another window that has another viewmodel. Imagine a textbox on the first window.
Once the second is opened the user will select a value and click save, this window will close and update the first window with its value.
When pushing save I have an ICommand on the childwindows Viewmodel that calls the SaveMethod. I have the selected value stored in a property on the Child windows viewmodel.

But how do I update the Main Windows textbox with this value? I imagine I bind a property on the main windows view model, but unsure on how to continue.

Please advise, I can provide code examples if needed, but I think I may have explained it well enough,
oh and thanks to everyone at StackOverflow for the help on my questions I have learnt a lot.

4
please share some code of what you have tried so far.Gilad
you really need to show some code in order for anyone to help youCharlesMighty
Is the child window modal dialog? That means that you need to close the dialog in order to continue working in parent window. Mostly, it's the case. I have written an example of working with dialogs in mvvm here: stackoverflow.com/questions/501886/…. It demonstrates login window popup, where parent window's viewmodel accesses the child vmLiero

4 Answers

2
votes

This is pretty straightforward using the MVVM Light framework. For the purposes of demonstration I'm going to use a string as the value you're passing, but it's easy to construct a different message type for whatever you need to pass.

In the constructor of your first Window's ViewModel you register to receive NotificationMessages. NotificationMessages are used to send string messages:

public MyFirstViewModel()
{
    Messenger.Default.Register<NotificationMessage>(this, NotificationMessageReceived);
}

In the SaveMethod in your second Window's ViewModel you send a message with the value you want to pass. I'm using MyStringValue as the name of the property that stores the value chosen by the user in your second Window:

private void SaveMethod()
{
    MessengerInstance.Send(new NotificationMessage(MyStringValue));
}

When that message is received by the ViewModel of the first Window the NoitificationMessageReceived method is called. I'm going to put that value in a string property on the first ViewModel called MySavedValue:

private void NotificationMessageReceived(NotificationMessage msg)
{
    MySavedValue = msg.Notification;
}

In your View for the first Window you have a TextBox with its Text property bound to MySavedValue. This updates whenever MySavedValue is updated.

0
votes

In the parent viewmodel, you'll need a reference to the child viewmodel. When the child window is closed, you'll want to get the value of the secondviewmodel's property and set it to a appropriate property of the first parent viewmodel.

0
votes

One of the posible (and simple) solutions is to keep one ViewModel for both windows

<Grid>
    <StackPanel>
        <TextBox Text="{Binding TheText}" />
        <Button Command="{Binding ShowOptionsCommand}" Content="..."/>
    </StackPanel>
    <Popup IsOpen="{Binding IsShowingOptions}">
        <StackPanel>
            <ListBox ItemsSource="{Binding Options}" 
                    SelectedItem="{Binding SelectedOption,Mode=TwoWay}"/>
            <Button Command="{Binding SaveOption}">Save</Button>
        </StackPanel>
    </Popup>
</Grid>

//ShowOptionsCommand handler
void ShowOptions() 
{
    IsShowingOptions = true;
}
//SaveOptionCommand handler
void SaveOption() 
{
    TheText = SelectedOption;
    IsShowingOptions = false;
}

I'm using the Popup to simplify the example.

0
votes

Personally I'd go with the mvvm light framework already mentioned, but another option is to leverage IOC, also included with the above framework.

With this pattern view models have interfaces and are bound as properties from a view model locator data source. Within that, the child view model can be injected to the parent view model. Because IOC can create singleton instances of objects, the same instance gets given to the parent as is bound to the child window. That way you get a reference to the view model but through an interface thus preserving the separation.

Just offering this as an alternative technical solution beyond those already offered.