Home > Software engineering >  How to prevent a ViewModel constructor from being called twice?
How to prevent a ViewModel constructor from being called twice?

Time:01-27

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?

CodePudding user response:

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}"
>
  •  Tags:  
  • Related