Search code examples
c#wpfmvvmcatel

Creating a ViewModel from a model


I am using framework Catel and I have a View with a TabControl which is being fed by an itemsource. TabContent was done with a Datatemplate and inside it has commands. One of those commands needs to open a new Window showing the content from the TabContent.

What am I trying to do? I am placing the command to open the the new Window in the model (Because from DataTemplate you are in the model context). Command is called correctly, however, I cannot refer to an ViewModel object from my Model.

I will write here a short version of my code to show better the problem.

My View is:

...
<TabControl Grid.Column="2" ItemsSource="{Binding Plots}" >
    ...
    <views:TabContent.Template>
        <DataTemplate>
            <Grid>
                ...
                    <DockPanel Grid.Column="0">
                        <ToolBarTray DockPanel.Dock="Left" Orientation="Vertical">
                            <ToolBar>
                                <Button Command="{Binding ShowAnotherWindow}">
                                    <Image Source="{StaticResource GalleryPropertyImage}" />
                                </Button>
                            </ToolBar>
                        </ToolBarTray>
                    </DockPanel>

                ...
            </Grid>
        </DataTemplate>
    </views:TabContent.Template>
</TabControl>
...

And inside my Model I have the command ShowAnotherWindow which is executed, but I cannot do something like:

CompletePlotViewModel viewModel = new CompletePlotViewModel(this);

What do you recommend me to do?


Solution

  • Even though the binding context is the model in the data template, it's still very wrong to put commands inside a model. They should live in the view model.

    What you can do is this:

    <TabControl x:Name="tabControl" Grid.Column="2" ItemsSource="{Binding Plots}" >
    

    Then you can use this binding:

    <views:TabContent.Template>
        <DataTemplate>
            <Grid>
                ...
                    <DockPanel Grid.Column="0">
                        <ToolBarTray DockPanel.Dock="Left" Orientation="Vertical">
                            <ToolBar>
                                <Button Command="{Binding ElementName=tabControl, Path=DataContext.ShowAnotherWindow}" CommandParameter="{Binding }">
                                    <Image Source="{StaticResource GalleryPropertyImage}" />
                                </Button>
                            </ToolBar>
                        </ToolBarTray>
                    </DockPanel>
    
                ...
            </Grid>
        </DataTemplate>
    </views:TabContent.Template>
    

    As you can see this now binds to the ShowAnotherWindow on the viewmodel. It passes the model as command parameter so you can use that as parameter in your command.