【问题标题】:Accessing a static property of a view model is null访问视图模型的静态属性为空
【发布时间】:2018-12-08 15:23:20
【问题描述】:

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

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

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

【问题讨论】:

  • 你不能让你的子设置视图模型成为主窗口视图模型的孩子吗?
  • 我该怎么做?当前设置从主视图加载为用户控件。这不算是个孩子吗?
  • 如果您首先使用视图模型,那么它将从您的主窗口视图模型中的视图模型中模板化。所以你可以传递你喜欢的任何东西,你会知道你的视图模型肯定是完全实例化的,因为它控制着用户控件需要的数据。
  • 添加到 OP 我的主视图正在做什么,然后我只是绑定到基于单选按钮的选定视图模型。对不起,我对此太天真了。

标签: c# wpf mvvm


【解决方案1】:

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 实例存储在字典中,它只是每次都实例化。

【讨论】:

  • 您的解释与我的设置非常接近。添加 Window.DataContext 会使 VS2017 一直处于无响应状态。也许这就是你提到的奇怪之处。
  • 不,不是。你确定这是视图模型而不是视图吗?因为后者会无限循环。
  • 与 d:DataContext="{d:DesignInstance main:MainWindowVM, IsDesignTimeCreatable=True}" 冲突,但在我的 settingsvm 构造函数中仍然为空。
  • 删除设计器上下文。如果它是唯一实例化 subvm 的东西,主主窗口视图模型怎么可能为空?前者必须被实例化。
  • 你不能这么说,这是我的问题 :) 开始认为它与 MaterialDesignThemes 有关。不知何故,它必须首先创建 settingsvm。
猜你喜欢
  • 1970-01-01
  • 2018-04-18
  • 1970-01-01
  • 2015-10-22
  • 1970-01-01
  • 2012-12-30
  • 2013-12-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多