无法在另一个 ViewModel 中使用来自 MainViewModel 的数据

Can't use data from MainViewModel in another ViewModel

我对 MVVMtwo Views 以及相应的 ViewModels 有疑问。

我有一个 MainViewModelSettingsViewModel

MainViewModel 在程序开始时执行,从 xml 文件读取设置。 如果我在主视图中单击“设置”按钮,SettingsView 将使用绑定 SettingsViewModel 打开,并且应该用数据填充表格。 但问题是如何从 MainViewModel 获取数据到 SettingsViewModel

SettingViewModel 中,我没有 MainViewModel 的参考。我怎样才能得到这个?

我的第一个想法是在构造函数上设置数据,但我不能为此使用构造函数,因为我在 App.xaml 中获得了带有 DataTemplate 的视图实例:

        <DataTemplate DataType="{x:Type viewmodels:SettingsViewModel}">
          <views:SettingsView/>
        </DataTemplate>

我的第二个想法是用事件来解决它。但这也不起作用,因为我没有在 MainViewModel.

中得到 SettingsViewModel 的引用

这是我第一个使用 MVVM 模式的项目。可能是我的理解问题

一周以来我一直在努力解决这个问题,现在我非常绝望。

为了更好地理解,我在 Github 上创建了一个示例项目: https://github.com/fgth/Example

请帮助我 - 谢谢。

This is my first project using MVVM pattern. Maybe it's an understanding problem of mine.

您的 MVVM 分层很好。

  • 模型:设置
  • 视图模型:设置视图模型
  • 视图:设置视图

在父 MainViewModel 上存储/使用 Settings 实例也很有意义。

您的问题更多是静态与实例的误解。

SettingsView 中,您将 SettingsViewModel 定义为静态资源。这意味着每次解析 SettingsView 时都会调用其默认构造函数。

<UserControl x:Class="Example.Views.SettingsView"
             ...
             >
    <UserControl.Resources>
        <ResourceDictionary>
            <vms:SettingsViewModel x:Key="settingsvm"/>
        </ResourceDictionary>
    </UserControl.Resources>
    <StackPanel DataContext="{StaticResource settingsvm}">
        ...
    </StackPanel>
</UserControl>

鉴于您在 SettingsViewModel 构造函数中创建了一个新的 Settings 实例,您将始终以一张白纸告终。

public SettingsViewModel()
{
    Mysettings = new Settings();
    ...
}

最好在每个请求中将 Settings 实例从 MainViewModel 传递到 SettingsViewModel

ActualPage = new SettingsViewModel(mysettings);

使用依赖注入的更新构造函数。

public SettingsViewModel(Settings settings)
{
    Mysettings = settings;
    ...
}

不是 DataTemplate 流抱怨构造函数,它只是匹配类型。然而,静态资源确实需要一个无参数的构造函数,但我们同样不需要/不想要该功能。更新 SettingsView 后,一切都应该按预期工作。

<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>

请注意,我们让 DataContext 隐式流过,这(通常)是良好设计的标志。