Search code examples
c#wpfxamlmvvmdatacontext

Is it possible to get the DataContext(ViewModel) of a parent view element from within a childs DataContext(ViewModel)?


I have a Window with a Grid, which has a "MainWindowViewModel" set as its DataContext

<Grid x:Name="MainGrid">
    <Grid.DataContext>
        <view:MainWindowViewModel/>
    </Grid.DataContext>
<!-- ... -->
</Grid>

This MainGrid has two SubGrids (not named) and one of them contains a Frame which displays Pages. The Pages displayed have other ViewModels set as their DataContext.

<Page.DataContext>
    <view:AddOrderViewModel/>
</Page.DataContext>

In the MainWindowViewModel I have a Property "User". I want to access this Property from the ViewModel of the Page.

Is that even possible (without using "code behind"). I dont really know where to start since I dont know how to get the FrameworkElement using the ViewModel from within the ViewModel (I guess from there its only handling the visual tree?)

Any help, or push in the right direction would be greatly appreciated. Also if you have a better idea of how to pass the property from one ViewModel to the other, feel free to share :)

Thanks


Solution

  • I would suggest to try MVVM Light's Messenger. It is thoroughly enough explained here

    You create a class where you place the object property you want to send between ViewModels

    public class MessageClassName
    {
        public object MyProperty { get; set;}
    }
    

    Assuming you want to send the property from ViewModel1 to ViewModel2, you create a method in ViewModel1

    private void SendProperty(object myProperty)
    {
        Messenger.Default.Send<MessageClassName>(new MessageClassName() { MyProperty = myProperty });
    }
    

    Then you are calling it from your code when you want it to be sent.

    SendProperty(_myProperty);
    

    In the constructor of ViewModel2 you register to that message

    public ViewModel2()
    {
        Messenger.Default.Register<MessageClassName>(this, (message) =>
        {
             ReceiveProperty(message.MyProperty);
        )};
    }
    

    Then also in ViewModel2 you define the method ReceiveProperty

    private void ReceiveProperty(object myProperty)
    {
        ...Do whatever with myProperty here...
    }
    

    Note that you need to add

    using GalaSoft.MvvmLight.Messaging;
    

    in both ViewModel1 and ViewModel2 classes