2010-01-10 15 views
5

Estoy usando MVVM y cada vista se asigna a un ViewModel con una convención. IE MyApp.Views.MainWindowView MyApp.ViewModels.MainWindowViewModelDataTemplate + MVVM

¿Hay una manera de quitar la DataTemplate y hacerlo en C#? con algún tipo de bucle?

<DataTemplate DataType="{x:Type vm:MainWindowViewModel}"> 
    <vw:MainWindowView /> 
</DataTemplate> 

Respuesta

6

Así que, básicamente, es necesario crear plantillas de datos mediante programación ... Eso no es muy sencillo, pero creo que se puede lograr que con la clase 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); 
} 

no he probado que , por lo que pueden ser necesarios algunos ajustes ... Por ejemplo, no estoy seguro de cuál debe ser el tipo de la clave de recursos, ya que generalmente se establece implícitamente al configurar el Tipo de datos en XAML

6

Gracias Thomas, usando su código, he hecho esto.

Es necesario utilizar el DataTemplateKey al agregar los resoures: 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); 
     } 
    }