如何在不创建ViewModel对象的情况下指定DataContext(ViewModel)类型以在XAML编辑器中进行设计时绑定检查? [英] How do I specify DataContext (ViewModel) type to get design-time binding checking in XAML editor without creating a ViewModel object?

查看:248
本文介绍了如何在不创建ViewModel对象的情况下指定DataContext(ViewModel)类型以在XAML编辑器中进行设计时绑定检查?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我可以这样指定DataContext:

I can specify DataContext like this:

<Window ... >
    <Window.DataContext>
        <MainViewModel />
    </Window.DataContext>
    ...
</Window>

在这种情况下,WPF将创建MainViewModel类型的对象,并将其分配给窗口的DataContext属性(这发生在Window的InitializeComponent()方法内部).

And in this case WPF will create an object of type MainViewModel and assign it to the window's DataContext property (this happens inside Window's InitializeComponent() method).

但是如果我的ViewModel没有默认构造函数怎么办.或者如果我想在执行Window.InitializeComponent()之后初始化ViewModel并将其分配给DataContext(在Window的构造函数中或从实例化该窗口的同一代码中),该怎么办-在这种情况下,WPF创建一个ViewModel(在InitializeComponent()内部),将其分配给它到窗口的DataContext,然后用另一个ViewModel实例覆盖它(我担心这里不必要的对象实例化).

But what if my ViewModel doesn't have a default constructor. Or what if I want to initialize ViewModel and assign it to DataContext after Window.InitializeComponent() is executed (inside Window's constructor or from the same code which instantiates the window) - in this case WPF creates a ViewModel (inside InitializeComponent()), assigns it to window's DataContext and then I overwrite it with another instance of ViewModel (I'm worried about unnecessary object instantiation here).

我只想指定ViewModel类型,所以如果我在{Binding}内(或重命名属性后)错误拼写了属性名称,则会收到设计时警告,或者我可以转到通过单击(在XAML中){Binding PropertyName}内的属性名称进行声明.

I would like to be able to specify just a type of ViewModel, so I would get design-time warning if I misspell a property name inside {Binding} (or after renaming the property), or I could Go To Declaration by clicking (in XAML) on a property name inside {Binding PropertyName}.

感谢您的宝贵时间.

推荐答案

如果您自己动手制作MVVM,那将是棘手的部分.

That's the tricky part if you do the do-it-yourself MVVM.

您的选择基本上是:

使用依赖注入

您可以将ViewModel注入到Page/Window的构造函数中,并在其中分配它.

You could inject the ViewModel in your Page/Window's constructor and assign it within it.

这有一些缺点.

  • 难以使用设计时视图模型
  • 无法再从XAML实例化视图

首先使用导航服务的ViewModel

您将解析ViewModels并通过导航服务进行所有导航.在您的ViewModels中,传递一个INavigationService.您可以使用ViewModel类型导航到视图.在其内部通过Dependency Injection实例化ViewModel,然后实例化View(基于命名约定或通过DI配置)

You'd resolve your ViewModels and do all your navigation via a navigation service. In your ViewModels you pass the an INavigationService. You could navigate to a view by using ViewModel type. Inside it instantiate the ViewModel via Dependency Injection, then instantiate the View (based on naming conventions or via DI configuration)

更好一点,但是仍然不允许您在XAML中实例化视图.最大的优点是,它使您可以轻松地将参数传递给ViewModel(具有使用NavigatedTo方法的ViewModels实现INavigationAware属性,该方法在实例化并将参数传递给之后调用)

That's a bit better, but still won't allow you to instantiate the Views within XAML. Big plus is, it allows you easily to pass parameters to the ViewModel (having the ViewModels implement INavigationAware property with NavigatedTo method, which is called after instantiation and passing the parameter to)

ViewModelLocator/附加属性/行为

通过此操作,您将创建一个附加属性,将该属性设置为true(即自动装配)或ViewModel类型(以便对实例化的ViewModel进行更多控制),然后查找并解析ViewModel并分配它.

With this one, you would create an attached property, which you either set to true (i.e. autowire) or to a ViewModel type (to have more control over the ViewModel instantiated) and the find and resolve the ViewModel and assign it.

基本上,它提供了以上所有优点以及实例化视图View.

It basically gives all of the advantages above plus instantiation form View.

最后一个基本上是Microsoft MVVM框架"Prism"的功能(导航服务navigationService.Navigate("MyPage", myParameterForViewModel),DataContext实例化以及通过自动装配从XAML进行分配(在XAML:prism:ViewModelLocator.AutoWireViewModel="True"中).

Last one is basically what Microsoft's MVVM framework "Prism" does (navigation service navigationService.Navigate("MyPage", myParameterForViewModel), DataContext instantiation and assignment from XAML via autowireing (In XAML: prism:ViewModelLocator.AutoWireViewModel="True").

话虽如此,最好使用成熟的MVVM框架来完成这部分的连接工作(即使您决定不使用诸如BindableBase之类的基类或在该框架中调用的任何类).

That being said, it's best to use an matured MVVM Framework which does this parts of your wiring (even if you decide not to use the base classes such as BindableBase or whatever it's called in said framework).

关于设计时ViewModel/ViewModels的自动完成:

As for design-time ViewModel/auto-completition for ViewModels:

您可以使用Blend的设计时"属性来执行此操作.您需要首先添加Blend程序集引用.然后,您可以将xmlns:d="http://schemas.microsoft.com/expression/blend/2008"命名空间添加到页面/视图中.

You can use Blend's Design-Time attributes to do this. You need to add the Blend assembly references first. Then you can add xmlns:d="http://schemas.microsoft.com/expression/blend/2008" namespace into your page/view.

然后,您可以通过d:DataContext="{d:DesignInstance my:DesignTimeViewModel, IsDesignTimeCreatable=True}将其绑定到页面中.注意DataContext之前的d:,这很重要.仅在设计器(Visual Studio XAML设计器或Blend)中使用此DataContext.这是为了防止干扰正常的DataContext(不带前缀).

Then you can bind it into your page via d:DataContext="{d:DesignInstance my:DesignTimeViewModel, IsDesignTimeCreatable=True}. Notice the d: before the DataContext, this is important. This DataContext will only be used in the Designer (Visual Studio XAML Designer or in Blend). This is to prevent interfering with the normal DataContext (without the prefix).

示例:

<Window x:Class="WpfApplication1.Window2"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:myApp="clr-namespace:WpfApplication1"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d"
        d:DataContext="{d:DesignInstance myApp:Window2ViewModel, IsDesignTimeCreatable=True}">
    <Grid>
        <TextBlock Text ="{Binding Test}"/>
    </Grid>
</Window>

如果您对ViewModel使用接口,则只需使Visual Studio实现所有Interface属性并为其提供一些默认值(对于该属性,以便在ViewModel中具有示例数据以验证绑定),即可很快创建设计实例.正常工作).

If you use Interfaces for your ViewModels, it's pretty fast to create the Design Instance, by simply having Visual Studio implement all the Interface property and give it some default values (for property so you have example data in your ViewModel to verify bindings work correctly).

这需要您创建单独的设计时ViewModel和实际的ViewModel,这并不像听起来那样糟糕.即使真正的ViewModel尚未完成/实现,这也为您的UI设计人员提供了使用它的机会.

This requires you to create separate design-time ViewModels and your actual ViewModels, which isn't as bad as it sounds. This gives your UI designer the chance to work with it, even if the real ViewModel isn't finished/implemented yet.

这篇关于如何在不创建ViewModel对象的情况下指定DataContext(ViewModel)类型以在XAML编辑器中进行设计时绑定检查?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆