Search code examples
c#wpfmvvmuser-controls

Accesing properties in a UserControl from the MainWindow (WPF/MVVM)


I have a little problem and I'm looking the correct way to implement it.

I have a MainWindow and a UserControl to display some result, in the MainWindow I have a button "load" to load some data and the UserControl should display them.

I'm not sure what is the correct way to do this in WPF and MVVM:

Should I pass the MainWindowModel to the UserControlModel?;

Should I pass the UserControlModel to the MainWindowModel?;

Should I expose the property I need to fill as DependencyProperty in my UserControl and then fill it on the MainWindow?

Any suggestion would be appreciated. Thanks!

Edit 1: This is how I call my UserControl:

<TabControl Grid.Row="1"
            Grid.RowSpan="2"
            Grid.Column="0"
            VerticalAlignment="Stretch">

    <!--Result View-->
    <TabItem Header="{Binding TabImportHeader}">
        <results:ResultView/>
    </TabItem>

    <!--Configuration Tab-->
    <TabItem Header="{Binding TabConfigurationHeader}">
        <configuration:ConfigurationView />
    </TabItem>
</TabControl>

My UserControl where my problem appear is the ResultView


Solution

  • MainWindowVMInstance.UserControlVMInstance.Property

    The UserControl is inside your MainWindow.

    Therefore your MainWindow has a property (/instance) of your UserControlVM.

    Note: If you also need a reference of MainWindowVM inside your UserControlVM, pass it to the constructor and store it as property.

    In xaml it would look like this (inside MainWindow.xaml):

    <ContentControl Content="{Binding UserControlVMInstance}"/>
    

    Don't forget the DataTemplate:

    <DataTemplate DataType="{x:Type vm:UserControlVM}">
        <view:UserControlView/>
    </DataTemplate>
    

    Edit after question update:

    This is an example with a part of your code to demonstrate WPF and MVVM in action. You simply define a DataTemplate in your UserControl.Resources and then give the ContentControl via Binding an instance of your UserControlVM. WPF knows there's a DataTemplate for this type and will add an instance of the UserControlView where the ContentControl is.

    <MainWindow>
        <MainWindow.Resources>
            <DataTemplate DataType="{x:Type vm:UserControlVM}">
                <view:UserControlView/>
            </DataTemplate>
        </MainWindow.Resources>
    
        <!-- Your TabControl -->
        <TabControl>
            <!--Result View-->
            <TabItem Header="{Binding TabImportHeader}">
                <ContentControl Content="{Binding TabImportCONTENT}"/>
            </TabItem>
        </TabControl>
    </MainWindow>