2012-09-19 26 views
5

Estoy comenzando un nuevo proyecto y orienté mi estructura de proyecto en la estructura recomendada en this question.La vista no encuentra ViewModel en un ensamblaje diferente

Ahora estoy viendo un comportamiento extraño. Cuando configuro el contexto de datos en View-XAML, no se encuentra en tiempo de ejecución (obteniendo un XamlParseException). Cuando lo configuro en el constructor en codebehind-file, todo está funcionando bien.

¿Este comportamiento (documentado) es oficial al usar diferentes ensamblajes, o estoy haciendo algo mal?

El código:

que no trabaja:

MainView.xaml:

<UserControl x:Class="ViewsRoot.Views.MainView"    
     xmlns:baseControls="clr-namespace:BaseControls;assembly=BaseControls"    
     xmlns:viewModels="clr-namespace:ViewModelsRoot;assembly=ViewModelsRoot"> 
<UserControl.DataContext> 
    <viewModels:ShellViewModel /> 
</UserControl.DataContext> 

MainView.xaml.cs

public MainView() 
{ 
    InitializeComponent(); 
    // No DataContext set in codebehind-file  
} 

de Trabajo:

MainView.xaml:

<UserControl x:Class="ViewsRoot.Views.MainView"    
     xmlns:baseControls="clr-namespace:BaseControls;assembly=BaseControls"    
     xmlns:viewModels="clr-namespace:ViewModelsRoot;assembly=ViewModelsRoot"> 
<!--<UserControl.DataContext> 
    <viewModels:ShellViewModel /> 
</UserControl.DataContext> --> 

MainView.xaml.cs:

public MainView() 
{ 
    InitializeComponent(); 
    DataContext = new ViewModelsRoot.ShellViewModel(); 
} 

Actualización:

La Excepción de texto es:

{ "El archivo o ensamblado \ "ViewModelsRoot, PublicKeyToken = null \" o una de sus dependencias no se encontró. El sistema no puede encontrar el archivo especificado "}

Y la única excepción interna que puedo ver es una System.IO.FileNotFoundException

Actualización 2:..

Gracias por los comentarios, pero no he Olvidé un espacio de nombres. Lo acorté aquí para mostrar el código, pero volví a marcar doble y triplete (otra vez). El espacio de nombres DataContexts también se rellena con intellisense. Todo el <viewModels:ShellViewModel /> está escrito por intelli-sense. Por lo tanto, se encuentra en designtime ... ... ¿así que más ideas?

Actualización 3: El xaml se analiza "correctamente" ya que puedo vincular el DataContext a una clase en el mismo ensamblaje.

+0

¿Hay alguna excepción interna? – Guillaume

+0

@Guillaume por favor vea mi pregunta actualizada :) – basti

+0

Es posible que haya olvidado algunos espacios de nombres en su 'UserControl'. Compruebe si esta ayuda: http://stackoverflow.com/questions/8852912/xamlparseexception-in-view – Guillaume

Respuesta

-1

A menudo he encontrado este error cuando el marco de trabajo del proyecto se configuró en "Perfil del cliente" (esto se configuró por defecto en VS2010, IIRC), si este es el caso, intente cambiarlo a 3.5 o 4.0.

+0

Lo siento. Sin suerte - es .net4 - Perfil completo. – basti

+0

¿Hay alguna posibilidad de que puedas subir tu proyecto para que pueda echar un vistazo? –

2

He reproducido este error utilizando una solución de proyecto de árboles, con las dependencias especificadas entre ellos:

  • StartupProject → ViewsRoot
  • ViewsRoot → ViewModelsRoot
  • ViewModelsRoot

"StartupProject" tiene el tipo de salida "exe", mientras que los otros dos tienen "dll".

En mi caso, he resuelto el problema agregando "ViewModelsRoot" a la lista de Referencias de "StartupProject". No es un problema de codificación, sino más bien un problema de tiempo de ejecución, porque "ViewModelsRoot.dll" no se copia a la carpeta de salida "StartupProject".

Cuando especifica el DataContext en el código subyacente, Visual Studio nota la necesidad de ese "dll" y lo agrega a la salida después de la compilación. Esto no ocurre cuando configura el DataContext desde XAML. Es complicado porque el ensamblado "ViewModelsRoot" se resuelve indirectamente a través de "ViewsRoot" en el tiempo de ejecución. Al agregarlo a la lista Referencias, se fuerza a Visual Studio a copiar el "dll" en ambos casos.

También puede copiar "ViewModelsRoot.dll" a la carpeta de salida directamente, pero no se actualizará cuando cambie el código.

+0

Esto es interesante. Tuve el mismo problema y lo resolví con esta solución, pero para mí es una solución sucia. No quiero tener esa referencia en mi proyecto de inicio y quiero que mis proyectos sean independientes. Noté que esto nunca me pasó en el pasado, pero en el pasado siempre tuve alguna referencia de codificación a un ViewModel. Entonces ... Un truco menos obvio es simplemente agregar una clase privada a su proyecto Views y llamarlo como quiera y simplemente agregar un campo a un ViewModel en el proyecto ViewModel. Ni siquiera tiene que ser instanciado, solo para referencia. –

Cuestiones relacionadas