Error de ReSharper WPF: “No se puede resolver el símbolo” MyVariable “debido a DataContext desconocido”

Estoy experimentando este error al usar WPF + XAML + MVVM en Visual Studio 2012.

No se puede resolver el símbolo “MiVariable” debido a un DataContext desconocido

¿Cuál es la solución?

Este error es producido por ReSharper al diseñar XAML para WPF, e indica que XAML no puede encontrar la clase que contiene enlaces de tiempo de ejecución. Esto generalmente indica que DataContext no está configurado correctamente.

Este error significa que:

  • Intellisense para XAML no funciona tan bien en el momento del diseño;
  • No se puede navegar automáticamente desde el XAML a la clase C # en tiempo de diseño usando Ctrl-Click en el binding en el XAML;
  • Cuando seleccionamos “Buscar usos” en una propiedad, no mostrará los usos en el XAML ni en el C #;
  • El diseñador no puede no mostrar datos en vivo desde una clase C # personalizada.

Para aquellos de nosotros que piensan en MVVM, este error indica que la Vista no puede encontrar ViewModel.

Solución 1

Vaya a través de algún tipo de tutorial web para comprender cómo funciona DataBinding. Recomienda Microsoft Data Binding Overview .

Solución 2

Si usa ReSharper, al presionar Alt-Enter en el DataContext ofensivo aparecerá un menú que le ayudará a insertar el DataContext correcto en su XAML.

Lo usé para resolver el problema correctamente.

enter image description here

Solución 3

En el panel “Propiedades” de Visual Studio, puede seleccionar el contexto de datos para el control seleccionado:

enter image description here

Solución 4

Blend también se puede usar para establecer el contexto de datos. Abra su archivo .sln en Blend, seleccione el elemento de diseño, luego en las propiedades, seleccione “Nuevo”:

enter image description here

Solución 5

DevExpress también puede ayudarlo a resolver este error en XAML, utilizando su asistente.

En XAML, seleccione el elemento principal para el que desea establecer el contexto de datos (generalmente el formulario completo), luego, en el diseñador, seleccione el triángulo de acción.

Luego, busque la clase con el código C #.

enter image description here

Sugerencia: la clase será invisible a menos que agregue un constructor sin parámetros a la clase.

XAML antes

  

XAML después

     

Sugerencia 6

Si no puede ver las tags inteligentes en el diseñador de WPF, verifique que no se hayan apagado en algún momento:

enter image description here

Solución 7

Se puede agregar una llamada de un fragmento de código en el inicio que aparece un cuadro de mensaje cada vez que hay un error de enlace. Esto ha resultado ser muy útil.

En caso de que el enlace web mencionado anteriormente baje, aquí está el código:

 public partial class Window1 : Window { public Window1() { BindingErrorTraceListener.SetTrace(); InitializeComponent(); } } 

Método:

 using System.Diagnostics; using System.Text; using System.Windows; namespace SOTC_BindingErrorTracer { public class BindingErrorTraceListener : DefaultTraceListener { private static BindingErrorTraceListener _Listener; public static void SetTrace() { SetTrace(SourceLevels.Error, TraceOptions.None); } public static void SetTrace(SourceLevels level, TraceOptions options) { if (_Listener == null) { _Listener = new BindingErrorTraceListener(); PresentationTraceSources.DataBindingSource.Listeners.Add(_Listener); } _Listener.TraceOutputOptions = options; PresentationTraceSources.DataBindingSource.Switch.Level = level; } public static void CloseTrace() { if (_Listener == null) { return; } _Listener.Flush(); _Listener.Close(); PresentationTraceSources.DataBindingSource.Listeners.Remove(_Listener); _Listener = null; } private StringBuilder _Message = new StringBuilder(); private BindingErrorTraceListener() { } public override void Write(string message) { _Message.Append(message); } public override void WriteLine(string message) { _Message.Append(message); var final = _Message.ToString(); _Message.Length = 0; MessageBox.Show(final, "Binding Error", MessageBoxButton.OK, MessageBoxImage.Error); } } } 

Solución 8

Use la utilidad gratuita Snoop .

Hay una característica realmente agradable que le permite filtrar por controles con errores de enlace. Esto le permite navegar directamente a la pantalla con el error de encuadernación.

Después de iniciar Snoop:

  1. Haga clic y arrastre el segundo icono de destino sobre su aplicación en ejecución.
  2. Mantenga presionadas las teclas Ctrl + Shift.
  3. A medida que mueva el mouse sobre la aplicación en ejecución, cualquier control que esté debajo del mouse se marcará en rojo.
  4. Suelta el mouse y Snoop mostrará una ventana que muestra todos los XAML en el árbol visual.

enter image description here

enter image description here

Sugerencia 9 – Design Time DataContext

En realidad, hay dos DataContexts completamente separados: design time y run time .

La mayoría de las soluciones anteriores se centran en establecer el run time DataContext.

Una vez que establezca el design time DataContext, la vista previa de XAML en Visual Studio o Blend mostrará datos personalizados proporcionados por su clase C # personalizada.

Si utilizo Blend, esta información personalizada también se puede leer desde un archivo XML, pero prefiero proporcionarla desde mi propia clase C #.

Para establecer el design time DataContext, ver:

  • Adam Prescott: Enlace de datos en tiempo de diseño en WPF
  • ¿Ver cambios de UI en la vista de diseño con WPF y XAML y enlace de datos?

O agregue esto a cualquier elemento (esto actualizará la clase MyClass en el momento del diseño, para que Intellisense funcione):

 d:DataContext="{d:DesignInstance d:Type=viewModel:MyClass, IsDesignTimeCreatable=True}" 

Y esto al encabezado:

 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" mc:Ignorable="d" 

Detrás de escena, cuando configura el design time DataContext:

  • El diseñador de Visual Studio (o Blend) instanciará automáticamente una nueva instancia de la clase a la que lo apunta. Esto también funciona si creas una clase estática.
  • Luego, en la vista previa de XAML, mientras edita el XAML, se mostrarán los datos en vivo de su clase C #.
  • Esto hace que el diseño sea muy rápido, ya que puede trabajar con datos en tiempo real en el momento del diseño, y no tiene que ejecutar el progtwig todo el tiempo para ver cómo se ve.

Tenga en cuenta que la vista previa de XAML solo aparece si está usando un Control de usuario. Si prefiere usar DataTemplates, no hay problema: puede crear un Control de usuario temporal que incluya DataTemplate y establecer el design time DataContext para apuntar a una clase estática. Codifique la clase estática para que cree una nueva instancia de su ViewModel (es decir, la clase a la que desea enlazarse). Por ejemplo, su clase estática podría leer datos de una base de datos, llenar las propiedades de ViewModel, y podría trabajar con datos en vivo de la base de datos en tiempo de diseño XAML.

Esta técnica también funciona perfectamente con Dependency Injection, como Unity o MEF. Debe apuntar su design time DataContext a una clase estática que toma las clases apropiadas del contenedor de dependency injection y configura todo. A continuación, puede ver los datos en vivo en el momento del diseño en la vista previa de XAML. La demostración de links mencionada anteriormente funciona de esta manera (¡completa con los videos de YouTube de un tic-tac en tiempo real en tiempo de diseño XAML!).

No hace falta decir que esta técnica funciona perfectamente con el patrón MVVM y también con MVVM + Dependency Injection. Para aquellos que no están familiarizados con MVVM, es una gran manera de producir proyectos elegantes, limpios, fáciles de mantener y fáciles de modificar. Microsoft Blend en sí está escrito completamente utilizando el patrón MVVM.