ViewModel 未在视图注入时初始化(WPF PRISM 4 MVVM)

发布于 2024-10-18 15:26:10 字数 2961 浏览 6 评论 0原文

我正在使用 PRISM4 MVVM 模式,并且当应用程序启动时,视图已成功加载并显示在适当的区域上。当应用程序启动时,ViewModels 会在视图加载时自动初始化。但是,如果我尝试在新选项卡(新区域)上注入新视图,则新视图的 ViewModel 不会初始化。下面是视图注入的代码:

IRegion region = regionManager.Regions["RegionNameGoesHere"];

var pane = new Views.ABCView() {Tag = id};
regionManager.Regions["RegionNameGoesHere"].Add(pane);

上面的代码打开一个新选项卡并加载新视图,但它不会初始化 ViewModel。控件的每个选项卡都是一个新区域(选项卡控件有一个 RegionAdapter)。

这是视图背后的代码:

using System.ComponentModel.Composition;
using System.Diagnostics.CodeAnalysis;
using System.Windows.Controls;
using Telerik.Windows.Controls;
using Telerik.Windows.Controls.Docking;

namespace Company.Application.Module.Assembly.Views
{
    [Infrastructure.Behaviours.ViewExport("ABCView")]
    [PartCreationPolicy(CreationPolicy.NonShared)]
    public partial class ABCView : RadPane
    {
        public ABCView()
        {
            this.InitializeComponent();
        }

        /// <summary>
        /// Sets the ViewModel.
        /// </summary>
        /// <remarks>
        /// This set-only property is annotated with the <see cref="ImportAttribute"/> so it is injected by MEF with
        /// the appropriate view model.
        /// </remarks>
        [Import]
        [SuppressMessage("Microsoft.Design", "CA1044:PropertiesShouldNotBeWriteOnly", Justification = "Needs to be a property to be composed by MEF")]
        ABCViewModel ViewModel
        {
            set
            {
                this.Decorator.DataContext = value;
                //this.DataContext = value;
            }
        }
    }
}

这是带有一些属性和事件的 ViewModel。我在上面的代码中缺少一些初始化下面的 ViewModel 的内容。任何建议都将不胜感激。

 using System;
 using System.Collections;
 using System.Collections.Generic;
 using System.Collections.ObjectModel;
 using System.Collections.Specialized;
 using System.ComponentModel.Composition;
 using System.Linq;
 using System.ServiceModel;
 using System.ServiceModel.Description;
 using System.Text;
 using System.Windows.Media;
 using System.Windows.Media.Imaging;
 using System.Xml;
 using System.Xml.XPath;
 using System.Windows.Data;

 using Microsoft.Practices.Prism.Commands;
 using Microsoft.Practices.Prism.Events;
 using Microsoft.Practices.Prism.Regions;
 using Microsoft.Practices.Prism.ViewModel;

 namespace Company.Application.Module.Assembly.Views
 {
     [Export(typeof(ABCViewModel))]
     [PartCreationPolicy(CreationPolicy.NonShared)]
     public class ABCViewModel : NotificationObject
     {
         private readonly IRegionManager regionManager;

         [ImportingConstructor]
         public ABCViewModel(IRegionManager regionManager)
         {
             // Event Aggregator
             //this.eventAggregator = eventAggregator;

             // Region Manager
             this.regionManager = regionManager;

         }

         #region P R O P E R T I E S

         #region E V E N T S 

     }
 }

I'm using PRISM4 MVVM Pattern, and the views are loaded successfully and displayed on the appropriate regions when the application starts. When the application starts, the ViewModels are initialized automatically when the view is loaded. However, if I try to inject a new view on a new tab (new region), the ViewModel of the new view is not initialized. Here's the code for view injection:

IRegion region = regionManager.Regions["RegionNameGoesHere"];

var pane = new Views.ABCView() {Tag = id};
regionManager.Regions["RegionNameGoesHere"].Add(pane);

The code above opens a new tab and load the new view, but it doesn't initialize the ViewModel. Each tab of the control is a new region (there's a RegionAdapter for the tab control).

Here's the code behind the view:

using System.ComponentModel.Composition;
using System.Diagnostics.CodeAnalysis;
using System.Windows.Controls;
using Telerik.Windows.Controls;
using Telerik.Windows.Controls.Docking;

namespace Company.Application.Module.Assembly.Views
{
    [Infrastructure.Behaviours.ViewExport("ABCView")]
    [PartCreationPolicy(CreationPolicy.NonShared)]
    public partial class ABCView : RadPane
    {
        public ABCView()
        {
            this.InitializeComponent();
        }

        /// <summary>
        /// Sets the ViewModel.
        /// </summary>
        /// <remarks>
        /// This set-only property is annotated with the <see cref="ImportAttribute"/> so it is injected by MEF with
        /// the appropriate view model.
        /// </remarks>
        [Import]
        [SuppressMessage("Microsoft.Design", "CA1044:PropertiesShouldNotBeWriteOnly", Justification = "Needs to be a property to be composed by MEF")]
        ABCViewModel ViewModel
        {
            set
            {
                this.Decorator.DataContext = value;
                //this.DataContext = value;
            }
        }
    }
}

And here's the ViewModel with a few properties and events. I'm missing something in the code above to initialize the ViewModel below. Any suggestion is greatly appreciated.

 using System;
 using System.Collections;
 using System.Collections.Generic;
 using System.Collections.ObjectModel;
 using System.Collections.Specialized;
 using System.ComponentModel.Composition;
 using System.Linq;
 using System.ServiceModel;
 using System.ServiceModel.Description;
 using System.Text;
 using System.Windows.Media;
 using System.Windows.Media.Imaging;
 using System.Xml;
 using System.Xml.XPath;
 using System.Windows.Data;

 using Microsoft.Practices.Prism.Commands;
 using Microsoft.Practices.Prism.Events;
 using Microsoft.Practices.Prism.Regions;
 using Microsoft.Practices.Prism.ViewModel;

 namespace Company.Application.Module.Assembly.Views
 {
     [Export(typeof(ABCViewModel))]
     [PartCreationPolicy(CreationPolicy.NonShared)]
     public class ABCViewModel : NotificationObject
     {
         private readonly IRegionManager regionManager;

         [ImportingConstructor]
         public ABCViewModel(IRegionManager regionManager)
         {
             // Event Aggregator
             //this.eventAggregator = eventAggregator;

             // Region Manager
             this.regionManager = regionManager;

         }

         #region P R O P E R T I E S

         #region E V E N T S 

     }
 }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

晚雾 2024-10-25 15:26:10

问题是您自己创建视图,而不是让 CompositionContainer 为您创建视图。 CompositionContainer 对您自己创建的对象一无所知,因此当您调用 new Views.ABCView() 时,导入不会神奇地得到满足。

使用原始 MEF,您可以调用 CompositionContainer.GetExports() 从容器中获取视图。 Prism 中可能有一些基础设施围绕此调用,但我对 Prism 不太了解,所以我不知道具体是什么。

The problem is that you are creating the view yourself instead of having the CompositionContainer create it for you. The CompositionContainer doesn't know anything about objects you create yourself, so when you call new Views.ABCView(), the imports aren't magically satisfied.

With raw MEF, you would call CompositionContainer.GetExports() to get a view from the container. There is probably some infrastructure in Prism that wraps around this call, but I don't know much about Prism so I don't know exactly what that would be.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文