C# MVVM MEF WindowFormHost
我目前正在尝试设计一个通过MEF导入加载viewmodels的应用程序 到目前为止还不错,我通过字典加载了每个vm数据模板,从一个viewmodel导航到另一个viewmodel 每次导航时,我都会在Shell(主窗口)中修改主contentPresenter的内容 其中一个viewmodel允许我为activeX控件(例如acrobat reader)显示WindowFormHost。由于WindowFormHost不允许绑定,我在viewmodel中创建了WindowFormHost,并将其绑定到视图中的ContentPresenter 这就是它失败的地方:当返回到同一个viewmodel时,会再次创建视图。。。抛出一个“元素已经是另一个元素的子元素。”错误 我怎样才能防止呢?重新加载视图时是否应卸载WindowFormHost?或者我可以保留视图实例,以便每个视图只保留一个实例,并让数据绑定更新控件吗?(它看起来更适合内存消耗) 谢谢你的帮助 [编辑] 已加载字典:C# MVVM MEF WindowFormHost,c#,wpf,mvvm,mef,C#,Wpf,Mvvm,Mef,我目前正在尝试设计一个通过MEF导入加载viewmodels的应用程序 到目前为止还不错,我通过字典加载了每个vm数据模板,从一个viewmodel导航到另一个viewmodel 每次导航时,我都会在Shell(主窗口)中修改主contentPresenter的内容 其中一个viewmodel允许我为activeX控件(例如acrobat reader)显示WindowFormHost。由于WindowFormHost不允许绑定,我在viewmodel中创建了WindowFormHost,并将其
<DataTemplate x:Shared="False" DataType="{x:Type vm:DAVPDC3DVIAControlViewModel}">
<vw:MyUserControl />
</DataTemplate>
虚拟机(主窗口)
//CurrentUC将主窗口视图绑定到控制器活动视图模型
public IViewModel CurrentUC
{
get
{
return myAddinManager.CurrentVM;
}
}
主要观点:
控制器(事件时显示模块):
我还在WPF中使用Prism v4和MVVM处理一个项目(除了使用Unity)。我还需要使用至少两个控件,它们是必须托管在WindowsFormsHost中的Windows窗体控件。让我解释一下我对这个过程的看法 在我看来,您正在试图避免视图的代码隐藏中的任何代码。这是我能想到的将WindowsForms移到ViewModel中的唯一原因。我认为这根本是错误的做法。WindowsFormsHost的存在是为了显示图形化Windows窗体控件。因此,它属于视图 现在,我明白了数据绑定的吸引力。相信我,我一直希望能够对WindowForms控件的许多部分进行数据绑定。当然,要接受WPF数据绑定,该属性必须是依赖项对象上的依赖项属性。最简单的解决方案(并非不合理)是在代码隐藏中添加代码来配置windows窗体控件以供查看。将UI逻辑添加到ViewModel中实际上违反了MVVM设计模式,而添加代码隐藏则不是。(在某些情况下是最好的方法) 我见过可能的黑客试图绕过这个限制。包括使用插入数据绑定的“代理”,或者扩展WindowsFormsHost并添加封装特定托管控件属性的DependencyProperties,或者使用反射编写类并尝试插入windows窗体绑定。然而,我所看到的一切都不能完全解决这个问题。例如,我的windows窗体控件可以包含其他图形组件,这些组件也需要支持绑定 最简单的方法是简单地将视图与视图代码中的viewmodel同步。视图模型可以保留打开的文件或文档、文件名、标题等,但将显示和与显示相关的控件留给视图
最后,让我更直接地谈谈你的问题。我需要了解您是如何向MEF容器注册视图和ViewModel的,以及您是如何导航的,以了解您收到该错误的原因。在我看来,视图或视图模型被创建了不止一次,而另一个没有。这些是否已注册为单例类型?无论如何,我支持我所说的不在ViewModel中包含WindowsFormsHost的观点。我还在WPF中使用Prism v4和MVVM进行一个项目(使用Unity除外)。我还需要使用至少两个控件,它们是必须托管在WindowsFormsHost中的Windows窗体控件。让我解释一下我对这个过程的看法 在我看来,您正在试图避免视图的代码隐藏中的任何代码。这是我能想到的将WindowsForms移到ViewModel中的唯一原因。我认为这根本是错误的做法。WindowsFormsHost的存在是为了显示图形化Windows窗体控件。因此,它属于视图 现在,我明白了数据绑定的吸引力。相信我,我一直希望能够对WindowForms控件的许多部分进行数据绑定。当然,要接受WPF数据绑定,该属性必须是依赖项对象上的依赖项属性。最简单的解决方案(并非不合理)是在代码隐藏中添加代码来配置windows窗体控件以供查看。将UI逻辑添加到ViewModel中实际上违反了MVVM设计模式,而添加代码隐藏则不是。(在某些情况下是最好的方法) 我见过可能的黑客试图绕过这个限制。包括使用插入数据绑定的“代理”,或者扩展WindowsFormsHost并添加封装特定托管控件属性的DependencyProperties,或者使用反射编写类并尝试插入windows窗体绑定。然而,我所看到的一切都不能完全解决这个问题。例如,我的windows窗体控件可以包含其他图形组件,这些组件也需要支持绑定 最简单的方法是简单地将视图与视图代码中的viewmodel同步。视图模型可以保留打开的文件或文档、文件名、标题等,但将显示和与显示相关的控件留给视图 最后,让我更直接地谈谈你的问题。我需要了解您是如何向MEF容器注册视图和ViewModel的,以及您是如何导航的,以了解您收到该错误的原因。在我看来,e
[Export(typeof(IDAVPDC3DVIAControl))]
public partial class DAVPDC3DVIAControlViewModel : ViewModelBase, IViewModel, IPartImportsSatisfiedNotification
[Export]
public class MainWindowViewModel : ViewModelBase, IPartImportsSatisfiedNotification
public IViewModel CurrentUC
{
get
{
return myAddinManager.CurrentVM;
}
}
private void ModuleReadyEventAction(string iModuleName)
{
if (null != this.Modules && this.Modules.Count() > 0)
{
foreach (var item in Modules)
{
IBaseModule ibasemodule = item as IBaseModule;
if (null != ibasemodule)
{
Type tp = ibasemodule.GetType();
if (0 == tp.Name.CompareTo(iModuleName))
{
CurrentVM = ibasemodule.GetViewModel();
break;
}
}
}
}
}