Con*_*ngo 31 c# wpf xaml mvvm visual-studio-2012
我在Visual Studio 2012中使用WPF + XAML + MVVM时遇到此错误.
由于未知的DataContext,无法解析符号"MyVariable"
解决办法是什么?
Con*_*ngo 97
在为WPF设计XAML时,ReSharper会生成此错误,并指示XAML无法找到包含运行时绑定的类.这通常表示DataContext未正确设置.
此错误意味着:
bindingXAML中的Ctrl-Click,无法自动从XAML导航到C#类;对于我们这些在MVVM中思考的人来说,这个错误表明View无法找到ViewModel.
通过某种Web教程来了解DataBinding的工作原理.推荐Microsoft数据绑定概述.
如果使用ReSharper,在有问题的DataContext上按Alt-Enter将弹出一个菜单,帮助您将正确的DataContext插入XAML.
我用它来正确解决问题.

在Visual Studio的"属性"窗格中,您可以选择所选控件的数据上下文:

Blend也可用于设置数据上下文.在Blend中打开.sln文件,选择设计元素,然后在属性中选择"新建":

DevExpress还可以使用其向导帮助您在XAML中解决此错误.
在XAML中,选择要为其设置数据上下文的父元素(通常是整个表单),然后在设计器中选择操作三角形.
然后,使用C#代码浏览到该类.

提示:除非向类中添加无参数构造函数,否则该类将不可见.
<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">
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)
如果您无法在WPF设计器上看到智能标记,请检查它们是否在某些时候未关闭:

可以在启动时添加调用代码片段,每次出现绑定错误时都会弹出一个消息框.事实证明这非常有用.
如果前面提到的Web链接出现故障,请输入以下代码:
public partial class Window1 : Window
{
public Window1()
{
BindingErrorTraceListener.SetTrace();
InitializeComponent();
}
}
Run Code Online (Sandbox Code Playgroud)
方法:
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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
使用免费的实用程序Snoop.
有一个非常好的功能,允许您通过带有绑定错误的控件进行过滤.这允许您直接导航到具有绑定错误的视觉效果.
启动Snoop后:


实际上有两个完全独立的DataContexts:design time和run time.
以前的大多数解决方案都专注于设置run timeDataContext.
设置design timeDataContext后,Visual Studio或Blend中的XAML预览将显示自定义C#类提供的自定义数据.
如果使用Blend,也可以从XML文件中读取此自定义数据,但我更喜欢从我自己的C#类中提供它.
要设置design timeDataContext,请参阅:
或者,将此添加到任何元素(这将MyClass在设计时新增类,因此Intellisense将起作用):
d:DataContext="{d:DesignInstance d:Type=viewModel:MyClass, IsDesignTimeCreatable=True}"
Run Code Online (Sandbox Code Playgroud)
这个标题:
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
Run Code Online (Sandbox Code Playgroud)
在幕后,当您设置design timeDataContext时:
请注意,只有在使用用户控件时才会显示XAML预览.如果您更喜欢使用DataTemplates,那么没问题:您可以创建包含DataTemplate的临时用户控件,并将design timeDataContext 设置为指向静态类.对静态类进行编码,以便创建ViewModel的新实例(即要绑定的类).例如,您的静态类可以从数据库读取数据,填充ViewModel的属性,并且您可以在XAML设计时使用数据库中的实时数据.
这种技术也非常适用于依赖注入,例如Unity或MEF.您必须将design timeDataContext 指向一个静态类,该类从依赖项注入容器中获取适当的类,并设置所有内容.然后,您可以在XAML预览中的设计时查看实时数据.上述链接演示了这是如何工作的(在XAML设计时完成了直播时钟的YouTube视频!).
毋庸置疑,这种技术与MVVM模式以及MVVM +依赖注入非常吻合.对于那些不熟悉MVVM的人来说,它是制作优雅,干净,可维护且易于改变的项目的好方法.Microsoft Blend本身完全使用MVVM模式编写.