Reputation: 21
I have a Problem with MVVM
and two Views
and corresponding ViewModels
.
I have a MainViewModel
and SettingsViewModel
.
The MainViewModel
executes on program start reading settings from an xml file.
If I click on a Settings Button in the main view the SettingsView
will be open with the binding SettingsViewModel
and should fill the forms with Data.
But the Problem is how can I get the Data from the MainViewModel
to the SettingsViewModel
?.
In the SettingViewModel
I don't have a reference of the MainViewModel
. How can I get this?
My first idea was to set the Data over the constructor but I can't use the constructor for this because I get the instances of the View with DataTemplate
in the App.xaml
:
<DataTemplate DataType="{x:Type viewmodels:SettingsViewModel}">
<views:SettingsView/>
</DataTemplate>
My second idea was to solve it with Events. But that didn't work either because I don't get the reference of the SettingsViewModel
in the MainViewModel
.
This is my first project using MVVM
pattern. Maybe it's an understanding problem of mine.
I'm trying to solve this problem since one week and I'm very desperate now.
I created a sample Project on Github for better understanding: https://github.com/fgth/Example
Please help me - Thank you.
Upvotes: 0
Views: 303
Reputation: 11201
This is my first project using
MVVM
pattern. Maybe it's an understanding problem of mine.
Your MVVM layering is fine.
Storing / using the Settings
instance on the parent MainViewModel
also makes sense.
Your problem is more a static vs instance misunderstanding.
In SettingsView
you define your SettingsViewModel
as a static resource. Meaning its default constructor will be called every time a SettingsView
is resolved.
<UserControl x:Class="Example.Views.SettingsView"
...
>
<UserControl.Resources>
<ResourceDictionary>
<vms:SettingsViewModel x:Key="settingsvm"/>
</ResourceDictionary>
</UserControl.Resources>
<StackPanel DataContext="{StaticResource settingsvm}">
...
</StackPanel>
</UserControl>
Given you create a new Settings
instance in the SettingsViewModel
constructor, you'll always end up with a blank slate.
public SettingsViewModel()
{
Mysettings = new Settings();
...
}
It would be better to pass the Settings
instance from the MainViewModel
to the SettingsViewModel
on each request.
ActualPage = new SettingsViewModel(mysettings);
The updated constructor using Dependency Injection.
public SettingsViewModel(Settings settings)
{
Mysettings = settings;
...
}
It wasn't the DataTemplate
flow that was complaining about the constructor, it just matches types. However, the static resource did require a parameterless constructor, but again we don't need / want that functionality. After updating the SettingsView
everything should work as expected.
<UserControl x:Class="Example.Views.SettingsView"
...
>
<StackPanel>
<Label Margin="10" Content="TestView" HorizontalAlignment= "Center" FontSize="20"/>
<Label Margin="10" Content="TextBox" HorizontalAlignment= "Center"/>
<TextBox Width="200" Margin="0" Text="{Binding Mysettings.TextOfSetting}"/>
</StackPanel>
</UserControl>
Note we let the DataContext
flow through implicitly, which is (often) a sign of good design.
Upvotes: 1