【问题标题】:Can't use data from MainViewModel in another ViewModel无法在另一个 ViewModel 中使用来自 MainViewModel 的数据
【发布时间】:2021-01-01 13:03:19
【问题描述】:

我对@9​​87654322@ 和two 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

请帮助我 - 谢谢。

【问题讨论】:

  • 您可以将 SettingsViewModel 设为 MainViewModel 的属性。 MainViewModel如果从文件中读取设置,可以直接保存到它的属性SettingsViewModel,也就是SettingsView的DataContext。
  • 谢谢。我已经试过了。问题是,我用 ContentControl 元素更改了 Views(usercontrols)。如果我更改 ContentControl 上的视图,那么将创建一个新的视图模型实例,我没有得到这个参考。
  • 不应更改 ViewModel,它应该始终是同一个实例。如果 SettingsView 是 MainView 中的一个元素,您可以使用 &lt;SettingsView DataContext="{Binding SettingsViewModel}"/&gt; (assuming the property is named SettingsViewModel 将 SettingsViewModel 绑定到 SettingsView 以始终使用正确的 SettingsViewModel 实例。
  • 我正在使用带有绑定的 ContentControl 元素来更改 mainViewModel 中的视图。我在我的问题中添加了一个示例项目,您可以在那里看到它。
  • 选项 1:要么将设置视图模型作为主视图模型中的属性,然后相应地调用它。选项 2:创建一个单例类来保存数据。选项 3:设置一个 IOC 容器(可能是 over kill),并注册 mainviewmodel 和 settingsviewmodel。毫无问题地解决它们。

标签: c# .net wpf mvvm viewmodel


【解决方案1】:

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

您的 MVVM 分层很好。

  • 型号:设置
  • ViewModel:设置ViewModel
  • 视图:设置视图

在父 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 隐含地流过,这(通常)是良好设计的标志。

【讨论】:

  • 非常感谢。现在一切正常。
猜你喜欢
  • 2019-06-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-19
  • 1970-01-01
  • 1970-01-01
  • 2015-12-22
  • 1970-01-01
相关资源
最近更新 更多