我在 WPF 中创建了一个向导,其中包含作为 UserControl
对象的页面。我要做的是从包含以下内容的 .DLL 文件加载插件:
- 插件逻辑的代码文件。
- 一个 XAML 用户控件,它将显示插件的配置选项,显示在主向导中。
- 用户控件的 View 模型。
我已经能够成功加载并实例化 UserControl
对象以及 View 模型,而且我已经达到了控件按预期出现在它自己的向导页面中的阶段。
(这可能是正确实例化的 View 模型,因为我在 View 模型中设置了向导页面的标题并且一切正常)
我遇到的问题是我从 DLL 加载的 UserControl
没有正确显示。它不显示 UserControl
内容,它只显示 x:Class="MyDLL.MyCustomUserControl"
行中的明文 MyDLL.MyCustomUserControl
,其中实际的用户控件应该是。
我从 DLL 加载的用户控件的内容是:
<UserControl x:Class="MyDLL.MyCustomUserControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<StackPanel>
<Label Content="This is the Plugin Options Page" />
<TextBox Text="{Binding Path=PluginStringText}" />
</StackPanel>
</UserControl>
此用户控件
的 View 模型中存在属性PluginStringText
。
我有一种感觉,在从 DLL 加载 View 模型后,我需要以某种方式将 View 模型分配或绑定(bind)到用户控件。 作为向导的一部分,有一个部分用于定义数据模板(这是另一个包含向导页面的 UserControl),但我不知道如何在运行时实际添加额外的模板。我感觉这是导致问题的原因。
搜索许多主题表明我可能可以通过 View 的代码隐藏文件来完成此操作,但是我无法首先获得对 View 代码隐藏的引用以调用方法。有没有办法从 View 的 View Model 类中添加新的 DataTemplate 条目?
<UserControl.Resources>
<DataTemplate DataType="{x:Type viewModel:ExistingPage1ViewModel}">
<view:ExistingPage1View />
</DataTemplate>
<DataTemplate DataType="{x:Type viewModel:ExistingPage2ViewModel}">
<view:ExistingPage2View />
</DataTemplate>
<...>
如果有人能指出正确的方向,请提前致谢
最佳答案
我找到了解决这个问题的方法。 问题如我所料,ViewModel 数据类型与用于呈现 ViewModel 的 View 之间没有映射。
我在这里发现了一个有用的指南 http://www.ikriv.com/dev/wpf/DataTemplateCreation/其中解释了如何在代码中创建新的数据模板,这与您在 XAML 中对模板进行硬编码非常相似。
一切都很好,但我仍然必须找到一种方法来调用创建数据模板的方法。
好吧 - 事实证明我根本不需要在后面的代码中调用该方法!我只是将创建数据模板的方法直接放在负责填充向导页面的 View 模型中。
这还有一个额外的好处,就是我不必在 xaml 中对现有页面数据模板进行硬编码。
我将添加在 http://www.ikriv.com/dev/wpf/DataTemplateCreation/ 引用的代码供将来引用:
创建DataTemplate
对象的方法:
DataTemplate CreateTemplate(Type viewModelType, Type viewType)
{
const string xamlTemplate = "<DataTemplate DataType=\"{{x:Type vm:{0}}}\"><v:{1} /></DataTemplate>";
var xaml = String.Format(xamlTemplate, viewModelType.Name, viewType.Name, viewModelType.Namespace, viewType.Namespace);
var context = new ParserContext();
context.XamlTypeMapper = new XamlTypeMapper(new string[0]);
context.XamlTypeMapper.AddMappingProcessingInstruction("vm", viewModelType.Namespace, viewModelType.Assembly.FullName);
context.XamlTypeMapper.AddMappingProcessingInstruction("v", viewType.Namespace, viewType.Assembly.FullName);
context.XmlnsDictionary.Add("", "http://schemas.microsoft.com/winfx/2006/xaml/presentation");
context.XmlnsDictionary.Add("x", "http://schemas.microsoft.com/winfx/2006/xaml");
context.XmlnsDictionary.Add("vm", "vm");
context.XmlnsDictionary.Add("v", "v");
var template = (DataTemplate)XamlReader.Parse(xaml, context);
return template;
}
然后需要将此 DataTemplate
注册为应用程序资源:
注册数据模板:
Application.Current.Resources.Add(template.DataTemplateKey;, template);
再次感谢 Ivan Krivyakov 在 http://www.ikriv.com/dev/wpf/DataTemplateCreation/ 提供的代码
关于c# - 从 DLL 动态加载 WPF View 和 View 模型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20930227/