【问题标题】:Can I somehow tell Resharper about the type of the ViewModel?我可以以某种方式告诉 Resharper ViewModel 的类型吗?
【发布时间】:2015-10-07 23:26:34
【问题描述】:

我们在不同的程序集中有视图和视图模型。 Views 的程序集具有对 VM 的引用。 (有时我们需要后面的代码)。

ViewModel 的 DataContext 是在代码中设置的,而不是在 XAML 中。因此,无论是 VS,Resharper 都无法像智能感知那样提供帮助,而且 Resharper 也会给出很多警告。

我们可以在 XAML cmets 中为 Resharper 设置任何指令来说明我们打算将 View 与特定类型的 VM 一起使用吗?

更新:

很好的blogpost 作为已接受答案的补充。

【问题讨论】:

  • 不幸的是,Resharper 在将 ViewModel 放置在代码隐藏中时不会(也无法)解析它。唯一可行的方法是将其放置在 XAML 中 UIElement 的 .DataContext 属性中。你把它放在代码隐藏中的理由是什么,也许我可以提供进一步的帮助?
  • 我们对虚拟机使用构造函数依赖注入。 VM 可以通过 VmManager 相互访问。我们希望虚拟机有权决定导航的工作方式。视图根本没有转换,只是绑定到命令和属性。我们使用代码隐藏来调整 fokus 行为或输入。

标签: c# mvvm resharper


【解决方案1】:

我遇到了同样的问题,并通过使用 XAML 中的设计时支持在 XAML 编辑器中获得智能感知支持来解决它,这也满足 Resharper 绑定验证。

注意下面代码 sn-p 中使用的 d: 命名空间。这将在运行时被忽略。您还可以使用 ViewModelLocator,它将设计时(假)存储库添加到 IoC 容器,从而消除来自外部源(如 Web 服务或其他数据源)的任何依赖项。

XAML 设计时支持:

<local:ViewBase
    ...
    mc:Ignorable="d" 
    d:DataContext="{Binding Source={d:DesignInstance Type=viewModel:MainViewModel, IsDesignTimeCreatable=True}}">

XAML ViewModelLocator:

<local:ViewBase
    ...
    mc:Ignorable="d" 
    viewModel:ViewModelLocator.ViewModel="MainViewModel" >

ViewModelLocator:

    static ViewModelLocator()
    {
        if (DesignMode.DesignModeEnabled)
        {
            Container.RegisterType<IYourRepository, YourDesignTimeRepository>();
        }
        else
        {
            Container.RegisterType<IYourRepository, YourRuntimeRepository>();
        }

        Container.RegisterType<YourViewModel>();
    }

【讨论】:

  • 迄今为止最好的答案!
  • "命名空间前缀“mc”未定义"
【解决方案2】:

如果您将 ViewModel 设置为 XAML 中 UIElement 的 .DataContext 属性作为占位符,则当您在运行时通过构造函数注入的 ViewModel 设置它时,它将被替换。

所以你可以拥有

<UserControl.DataContext>
    <Pages:WelcomeLoadingViewModel />
</UserControl.DataContext>

然后在UserControls构造函数中有

public WelcomeLoading(WelcomeLoadingViewModel viewModel)
{
   this.DataContext = viewModel;
}

public HomePage()
{
   this.InitializeComponent();

   this.DataContext = ViewModelResolver.Resolve<HomePageViewModel>();

这意味着您将获得 Binding 和 Resharper 支持,因为它们可以反映 XAML 数据上下文中的 ViewModel。但也可以享受依赖注入视图模型的好处,因为虚拟机将在运行时从您的 DI 容器中被替换。

【讨论】:

  • 这意味着我们必须为我们的虚拟机提供无参数的构造函数。
  • 是的,但只是为了能够在 Xaml 中呈现它们。为 VM 使用普通的构造函数,但构造函数重载为空。请记住,因为您在构建视图时实际上是在热交换您的虚拟机——当虚拟机被创建并传递到代码隐藏时,DI 容器仍将使用更长的、DI 的构造函数来创建类。
  • 如果您非常担心使用空构造函数滥用虚拟机的可能性 - 如果在设计时未构造空构造函数,您总是可以抛出异常,因此可以安全地限制创建VM 以这种方式连接到 Xaml 布局引擎。 Windows.ApplicationModel.DesignMode.DesignModeEnabled 或 System.ComponentModel.DesignerProperties.GetIsInDesignMode 将检查此项。
  • 我更担心 View 会尝试应用绑定,这将导致读取需要注入依赖项的属性。我不记得在对象生命周期中第一次应用绑定是什么时候。我们也有复合 VM 和复合 V。
  • 如果设置了设计模式,只需在这些特定属性中添加一个条件即可返回默认值。
猜你喜欢
  • 1970-01-01
  • 2015-07-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-12
  • 2011-01-08
  • 1970-01-01
  • 2023-02-14
相关资源
最近更新 更多