lkjasd2
lkjasd2

Reputation: 84

How to prevent a ViewModel constructor from being called twice?

I am trying to implement the MVVM pattern and already have DataTemplates in App.xaml and bound the ViewModel as the DataContext.

App.xaml:

<DataTemplate DataType="{x:Type Models:InputViewModel}">
    <Views:InputView/>
</DataTemplate>

UserControl:

<UserControl.DataContext>
    <Models:InputViewModel/>
</UserControl.DataContext>

Now when I want to display a new view by command, I assign a new instance to the ViewModel property, which type is an abstract base class that extends all ViewModels.

public ICommand DisplayInputView
{
    get
    {
        return new DelegateCommand(action => ViewModel = new InputViewModel());
    }
}

This causes the constructor of the ViewModel to be called twice, once by the command and once by the constructor of the view. Therefore, parameters that I want to pass via command into the next view model are not taken into account.

public ICommand DisplayInputView
{
    get
    {
        return new DelegateCommand(Input);
    }
}

void Input(object control)
{
    ViewModel = new InputViewModel();
    InputViewModel.AuditControl = control as AuditControl ?? new AuditControl();
}

How can I define the DataTemplate and the Datacontex so that the constructor of the view model is executed only once and I can pass parameters by command?

Upvotes: 3

Views: 1162

Answers (1)

Richard Deeming
Richard Deeming

Reputation: 31198

Remove the <UserControl.DataContext> assignment from the markup. The DataContext will be inherited from the control that's bound to the ViewModel property, so you don't need to set it again.

If you want design-time binding, use a design-time data context:

<UserControl
    ...
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    xmlns:vm="clr-namespace:YourLocalNamespace"
    d:DataContext="{d:DesignInstance vm:InputViewModel}"
>

Upvotes: 3

Related Questions