我正在使用MVVM模式,每个视图都遵循一种约定,与一个ViewModel相对应。例如: MyApp.Views.MainWindowView MyApp.ViewModels.MainWindowViewModel
是否有一种方法可以在C#中移除DataTemplate并用某种循环方式实现呢?
<DataTemplate DataType="{x:Type vm:MainWindowViewModel}">
<vw:MainWindowView />
</DataTemplate>
我正在使用MVVM模式,每个视图都遵循一种约定,与一个ViewModel相对应。例如: MyApp.Views.MainWindowView MyApp.ViewModels.MainWindowViewModel
是否有一种方法可以在C#中移除DataTemplate并用某种循环方式实现呢?
<DataTemplate DataType="{x:Type vm:MainWindowViewModel}">
<vw:MainWindowView />
</DataTemplate>
基本上,您需要以编程方式创建数据模板... 这并不是很直观,但我认为您可以使用 FrameworkElementFactory
类来实现:
public void AddDataTemplateForView(Type viewType)
{
string viewModelTypeName = viewType.FullName + "Model";
Type viewModelType = Assembly.GetExecutingAssembly().GetType(viewModelTypeName);
DataTemplate template = new DataTemplate
{
DataType = viewModelType,
VisualTree = new FrameworkElementFactory(viewType)
};
this.Resources.Add(viewModelType, template);
}
我没有测试过,所以可能需要进行一些调整...例如,我不确定资源键的类型应该是什么,因为在XAML中设置DataType时通常会隐含设置。
谢谢Thomas,使用你的代码我已经完成了这个任务。
在添加资源时,需要使用DataTemplateKey:D
private void AddAllResources()
{
Type[] viewModelTypes = Assembly.GetAssembly(typeof(MainWindowViewModel)).GetTypes()
.Where(t => t.Namespace == "MyApp.ViewModels" && t.Name.EndsWith("ViewModel")).ToArray();
string viewName = null;
string viewFullName = null;
foreach (var vmt in viewModelTypes)
{
viewName = vmt.Name.Replace("ViewModel", "View");
viewFullName = String.Format("MyApp.Views.{0}, MyApp", viewName);
DataTemplate template = new DataTemplate
{
DataType = vmt,
VisualTree = new FrameworkElementFactory(Type.GetType(viewFullName, true))
};
this.Resources.Add(new DataTemplateKey(vmt), template);
}
}