首页 > 解决方案 > 访问视图模型的静态属性为 null

问题描述

在我的应用程序中,我需要从子设置视图模型中调用我的主视图模型中的方法来更改主视图中的选项卡控件。基本上它是选项卡控件中的视图模型列表。设置视图模型具有用于打开或关闭选项卡的复选框。

无论如何,我在实例的主视图模型中设置了一个静态属性。在我的设置视图模型构造函数中,我得到一个空响应,但是如果我在每个复选框属性更改上检索实例,它就可以工作。似乎是创建实例的时间问题。当主视图模型实例不为空时,是否有事件或什么可以告诉我?

 <Window.Resources>
    <DataTemplate DataType="{x:Type skyTelescope:SkyTelescopeVM}">
        <skyTelescope:SkyTelescopeV />
    </DataTemplate>
    <DataTemplate DataType="{x:Type rotator:RotatorVM}">
         <rotator:RotatorView />
    </DataTemplate>
    <DataTemplate DataType="{x:Type focuser:FocuserVM}">
          <focuser:FocuserView />
    </DataTemplate>
    <DataTemplate DataType="{x:Type settings:SettingsVM}">
        <settings:SettingsV />
    </DataTemplate>
</Window.Resources>

标签: c#wpfmvvm

解决方案


wpf 有很多东西要学,而且 mvvm 方法与事件驱动代码有很大不同。

您的标记看起来像您首先在做视图模型......或类似的东西。如果你有一个 MainWindowViewModel 公开一个 SubVM 属性。

将 SubVM 绑定到主窗口中内容控件的内容属性。将 SubVM 设置为视图模型的实例,例如 SettingsVM。然后使用匹配的数据模板在视图中对其进行模板化。您会看到 SettingsV 出现。SettingsV 的数据上下文是您的 SubVM。将 SettingsV 中的控件绑定到 SubVM 中的属性,值可以在它们之间传输。这使您可以控制何时在 MainWindowViewModel 中实例化 SettingsVM。因此,您“知道”您是否有它的实例。您可以在字典中缓存视图模型的实例。使用类型作为您的键,如果您的字典中没有它,您可以实例化一个,然后如果您想保留状态,则重新使用它。

您可以通过在 xaml 中定义 MainWindow 的 datacontext 来使 MainWindow 实例化 MainWindowViewModel。

  <Window.DataContext>
      <local:MainWindowViewModel/>
  </Window.DataContext>

首先使用视图模型,模板的工作方式很奇怪。如果您想重置(未绑定)视图状态,则需要先将 SubVM 属性设置为 null 来强制重新模板化。此命令将 Type 作为参数

    private RelayCommand<Type> navigateCommand;
    public RelayCommand<Type> NavigateCommand
    {
        get
        {
            return navigateCommand
              ?? (navigateCommand = new RelayCommand<Type>(
                vmType =>
                {
                    CurrentViewModel = null;
                    CurrentViewModel = Activator.CreateInstance(vmType);
                }));
        }
    }

显然,这不会将任何 vm 实例存储在字典中,它只是每次都实例化。


推荐阅读