I am experiencing this error when using WPF + XAML + MVVM in Visual Studio 2012.
Cannot resolve symbol ”MyVariable“ due to unknown DataContext
What is the solution?
This error is produced by ReSharper when designing XAML for WPF, and indicates that the XAML cannot find the class that contains run-time bindings. This usually indicates that the DataContext
is not set properly.
This error means that:
binding
in the XAML;For those of us that think in MVVM, this error indicates that the View cannot find the ViewModel.
Go through some sort of web tutorial to understand how DataBinding works. Recommend Microsoft Data Binding Overview.
If using ReSharper, pressing Alt-Enter on the offending DataContext will bring up a menu that helps you to insert the correct DataContext into your XAML.
I used this to correctly resolve the issue.
In the "Properties" pane of Visual Studio, you can select the data context for the selected control:
Blend can also be used to set the data context. Open up your .sln file in Blend, select the design element, then in the properties select "New":
DevExpress can also help to resolve this error in the XAML for you, using its wizard.
In the XAML, select the parent element you want to set the data context for (usually the entire form), then in the designer select the action triangle.
Then, browse to the class with the C# code.
Hint: The class will be invisible unless you add a parameterless constructor to the class.
<UserControl x:Class="DemoAllocation.MyActualView" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="300">
<UserControl xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:Implementation="clr-namespace:DemoAllocation.ViewModel.Implementation" x:Class="DemoAllocation.MyActualView" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="300"> <UserControl.DataContext> <Implementation:MyActualViewModel/> </UserControl.DataContext>
If you cannot see the Smart Tags on the WPF designer, check that they have not been switched off at some point:
One can add call a snippet of code on startup that pops up a message box every time there is a binding error. This has turned out to be very useful.
In case the aforementioned web link goes down, here is the code:
public partial class Window1 : Window { public Window1() { BindingErrorTraceListener.SetTrace(); InitializeComponent(); } }
Method:
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); } } }
Use the free utility Snoop.
There is a really nice feature that allows you to filter by controls with binding errors. This allows you to navigate straight to the visual with the binding error.
After starting Snoop:
There are actually two completely separate DataContexts: design time
and run time
.
Most of the previous solutions are focused on setting the run time
DataContext.
Once you set the design time
DataContext, the XAML preview in Visual Studio or Blend will show custom data provided by your custom C# class.
If using Blend, this custom data can also be read from an XML file, but I prefer to provide it from my own C# class.
To set the design time
DataContext, see:
Or, add this to any element (this will new up the class MyClass
at design time, so Intellisense will work):
d:DataContext="{d:DesignInstance d:Type=viewModel:MyClass, IsDesignTimeCreatable=True}"
And this to the header:
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" mc:Ignorable="d"
Behind the scenes, when you set the design time
DataContext:
Note that the XAML preview only appears if you are using a User Control. If you prefer to use DataTemplates, no problem: you can create a temporary User Control that includes the DataTemplate, and set the design time
DataContext to point at a static class. Code up the static class so that it creates a new instance of your ViewModel (i.e. the class you want to bind to). For example, your static class could read data from a database, populate the properties of the ViewModel, and you could work with live data from the database at XAML design time.
This technique also works perfectly well with Dependency Injection, such as Unity or MEF. You have to point your design time
DataContext at a static class which grabs the appropriate classes out of the dependency injection container, and sets everything up. You can then see live data at design time in the XAML preview. The aforementioned links demo how this works (complete with YouTube videos of a live ticking clock at XAML design time!).
Needless to say, this technique works perfectly well with the MVVM pattern, and also with MVVM + Dependency Injection. For those of you unfamiliar with MVVM, its a great way to produce elegant, clean, maintainable and easy-to-alter projects. Microsoft Blend itself is entirely written using the MVVM pattern.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With