mosquito87
mosquito87

Reputation: 4440

WPF datatemplates and automatically created object of viewModel

I would like to implement navigation in my WPF application (using MVVM pattern). The following ViewModels exist:

To let WPF decide which view has to be shown in the "frame", I use DataTemplates, declared in App.xaml like that:

<Application x:Class="MyProject.App"
                xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                xmlns:viewModels="clr-namespace:MyProject.ViewModels"
                xmlns:views="clr-namespace:MyProject"
                StartupUri="MainWindow.xaml">
    <Application.Resources>
        <BooleanToVisibilityConverter x:Key="BoolToVis"/>
        <DataTemplate DataType="{x:Type viewModels:ConsignorViewModel}">
            <views:ConsignorUC />
        </DataTemplate>
        <DataTemplate DataType="{x:Type viewModels:RecipientViewModel}">
            <views:RecipientUC />
        </DataTemplate>
    </Application.Resources>
</Application>

My MainViewModel has a property "CurrentViewModel" of type ViewModel (my base class). A ConsignorViewModel and a RecipientViewModel is a ViewModel.

The view of the ConsignorViewModel is a "user control" (window didn't work with a ribbon).

<UserControl x:Class="MyProject.ConsignorUC"
             ...>
    <UserControl.DataContext>
        <local:ConsignorViewModel />
    </UserControl.DataContext>
    <Grid>
        ...
                <TextBox Name="searchterm" Margin="10,10,1,1" TextWrapping="Wrap" Text="{Binding SearchTerm, UpdateSourceTrigger=PropertyChanged}" Grid.Column="1" />
                ...
        </Grid>
    </Grid>
</UserControl>

The two-way-data binding isn't working in the child view. Did I miss something? Is it wrong to say that ConsignorViewModel has to be bound to the usercontrol?

Update I've found the problem, but not the solution: When starting the application, a new MainViewModel object is created. Thereby I say

currentViewModel = new ConsignorViewModel();

Now my child view is the ConsignorUC. When a new ConsignorUC is created, a new object of ConsignorViewModel is created. So I have to different objects of ConsignorViewModel, but I should have only one.

Upvotes: 0

Views: 1005

Answers (1)

dymanoid
dymanoid

Reputation: 15227

Your problem is actually here:

<UserControl.DataContext>
    <local:ConsignorViewModel />
</UserControl.DataContext>

You explicitly create a new view model and assign it to the DataContext property of the view on that view creation.

Just replace this with something like

<UserControl 
    x:Class="MyProject.ConsignorUC" 
    DataContext = "{Binding DataContext.CurrentViewModel, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}"/>

With this approach, you set the DataContext of your child view to the value of the CurrentViewModel property of your window's view model.

Upvotes: 3

Related Questions