我正在尝试使用WPF TreeView控件创建菜单。为此,我创建了一个接口,除了显示一些Read Only属性(菜单标题的一个项目和实际菜单项的一个项目)之外什么都不做,我可以将TreeView控件绑定到。
我创建的每个ViewModel都将实现此接口,并且两个属性的值将在属性的getter中进行硬编码。
是否可以使用反射来获取这些属性的值(在实例化之前),并将它们放入我的TreeView控件可以绑定到的某种形式的列表或数组中?
目标是不必将所有菜单项硬编码到TreeView,而是使用我到目前为止编写的所有ViewModel填充控件(即,每次创建视图模型时,它将“显示”在菜单,当然重新编译程序集后!)。
我可以使用以下方法获取影响界面的类的名称:
foreach (Type mytype in System.Reflection.Assembly.GetExecutingAssembly().GetTypes()
.Where(mytype => mytype.GetInterfaces().Contains(typeof(IInterfaceName))))
{
c.Add(mytype);
}
此代码用于获取实现接口的类的名称,但在此之后我陷入困境。
我想做的甚至可能吗?如果我没有走上正轨,我也会感谢任何其他方法来实现相同的结果。我不想在WPF中硬编码值,也不想在创建新的视图模型时将记录添加到数据库中。
这是我想要创建的内容的模拟: Mockup
答案 0 :(得分:1)
我强烈建议调查Managed Extensibility Framework(MEF)。 MVVM和MEF非常适合,因为MVVM的目标最终解决了单独的问题,而MEF是使松散耦合变得非常容易的技术。 MVVM关注的是将单独的层解耦,但是将不同的视图模型彼此解耦也是有利的(这基本上就是你要求的)。以下是如何开始使用MEF来实现您的特定问题的一个非常基本的示例。
首先,您需要为子视图模型创建一个接口:
public interface ISubViewModel
{
string Name { get; }
IView View { get; }
//... whatever else you need
}
现在,您将拥有某种父视图或主视图:
[Export]
public class ParentViewModel
{
[ImportMany] // <- this attribute tells MEF to look for all exports of type ISubViewModel
public IEnumerable<ISubViewModel> ViewModels { get; set; }
//... whatever else you need
}
现在您可以根据需要直接删除多个子视图模型,它们将自动显示在ParentViewModel的ViewModels属性中:
[Export(typeof(ISubViewModel))]
public class MySubViewModel1 : ISubViewModel { /* ... */ }
[Export(typeof(ISubViewModel))]
public class MySubViewModel2 : ISubViewModel { /* ... */ }
[Export(typeof(ISubViewModel))]
public class MySubViewModel3 : ISubViewModel { /* ... */ }
唯一剩下的就是设置MEF容器。要使[ImportMany]
属性在ParentViewModel
中工作,我们必须让MEF构建它。我们将设置容器并向其询问ParentViewModel
(也许这将在您的App.xaml.cs中)
public void Startup()
{
var catalog = new AggregateCatalog();
catalog.Catalogs.Add(new AssemblyCatalog(Assembly.GetExecutingAssembly()));
var container = new CompositionContainer(catalog);
var parentViewModel = container.GetExportedValue<ParentViewModel>();
parentViewModel.Show();
}
在幕后,MEF基本上以你在你的例子中尝试的方式使用反射,但是MEF使它变得更容易并且隐藏了你的所有反射丑陋,所有你需要做的就是添加适当的{{ 1}}和[Import]
属性。
使用MEF有点像异步/等待它倾向于&#34;入侵&#34;你的整个代码库。您创建的任何类都可以使用[Export]
或[Import]
(或构造函数注入,请参阅文档),只要它是[ImportMany]
- ed并由MEF检索它的实例。有关使用MEF的完整MVVM样式应用程序的一个很好的示例,请查看WAF示例(还有其他MVVM框架使用MEF或其他类型的DI,但我个人最多熟悉WAF)。
在整个应用程序中使用这样的MEF的结果将是一个非常模块化且松散耦合的应用程序,这对于可测试性来说非常可怕。