1

在我的应用程序中,我通常使用不带任何参数的 ViewModel 构造函数,并从 xaml 中找到我的 ViewModel,如下所示。

<UserControl.Resources>
    <ResourceDictionary>
        <vm:TabViewModel  x:Key ="vm" ></vm:TabViewModel>
    </ResourceDictionary>
</UserControl.Resources>

通过使用它,我可以在设计时在 xaml 中轻松引用我的 ViewModel 属性。

<Grid x:Name="grid" DataContext="{Binding Source={StaticResource ResourceKey=vm}}">

但是,由于我会在两个 ViewModel 之间进行通信,因此我开始使用Prism 6(事件聚合器)。

public TabViewModel(IEventAggregator eventAggregator)
    {
        this.eventAggregator = eventAggregator;
        tabPoco = new TabWindowPoco();

        tabPoco.Tag = "tag";
        tabPoco.Title = "Title";

        tabPoco.ListDataList = new ObservableCollection<ListData>();

        tabPoco.ListDataList.Add(new ListData() { Name = "First", Age = 10, Country = "Belgium" });
        tabPoco.ListDataList.Add(new ListData() { Name = "Second", Age = 11, Country = "USA" });
        tabPoco.ListDataList.Add(new ListData() { Name = "Third", Age = 12, Country = "France" });
    }

我正在使用Bootstrapper加载应用程序。

由于我使用的是 IEventAggregator,我不得不使用 prism:ViewModelLocator.AutoWireViewModel="True" 来定位 ViewModel。否则,应用程序不会运行。现在,我无法将 ViewModel 用作资源,也无法将其附加到 DataContext。

我不希望 Prism 自动定位相应的 ViewModel,我想控制它。我想在 xaml 中找到它并将其分配给 DataContext。

有谁知道我如何实现这一目标?

4

1 回答 1

1

这看起来像您未能设置您的依赖注入容器。依赖注入使用接口类型和具体类型之间的预设映射。您的映射将与此类似(Prism/EntLib 5 示例):

public class Bootstrapper : UnityBootstrapper
{
    protected override void ConfigureContainer()
    {
        base.ConfigureContainer();

        this.Container.RegisterType<IMyViewModel, SomeViewModel>();
        this.Container.RegisterType<IFooViewModel, SomeOtherViewModel>();
    }
}

稍后当您拨打电话时:

this.DataContext = container.Resolve<IMyViewModel>();

这比这个小例子所建议的更强大——你可以从你的容器(或区域管理器)中新建一个视图,并最终自动解决它的所有依赖关系。

要在 XAML 中维护智能感知等,您可以在 XAML 中指定视图模型的类型

<UserControl x:Class="YourNamespace.YourFancyView"
             ...
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:myNamespaceAlias="clr-namespace:PathToMyViewModelsInterface" 
             mc:Ignorable="d" 
             d:DesignHeight="100" d:DesignWidth="100"
             d:DataContext="{d:DesignInstance myNamespaceAlias:IMyViewModel, IsDesignTimeCreatable=False}" 
             ...
             >
</UserControl>

检查相关的 SO 问题How do I specify DataContext (ViewModel) type to get design-time binding checks in XAML editor without creating a ViewModel object? 在开发 WPF 用户控件时使用设计时数据绑定了解更多信息。

于 2018-02-19T09:36:41.027 回答