ReSharper WPF错误:“由于未知的DataContext,无法解析符号”MyVariable“

时间:2014-08-28 13:19:10

标签: c# wpf xaml visual-studio-2012 mvvm

在Visual Studio 2012中使用WPF + XAML + MVVM时遇到此错误。

  

由于未知的DataContext

,无法解析符号“MyVariable”

解决方案是什么?

1 个答案:

答案 0 :(得分:94)

在为WPF设计XAML时,ReSharper会生成此错误,并指示XAML无法找到包含运行时绑定的类。这通常表示DataContext未正确设置。

此错误表示:

  • XAML的智能感知在设计时不起作用;
  • 在设计时使用XAML中的binding按住Ctrl键单击,无法自动从XAML导航到C#类;
  • 当我们选择"查找用法"在属性上,它不会提出XAML中的用法以及C#;
  • 设计人员无法显示自定义C#类的实时数据。

对于我们这些在MVVM中思考的人来说,这个错误表明View无法找到ViewModel。

解决方案1 ​​

通过某种Web教程来了解DataBinding的工作原理。建议Microsoft Data Binding Overview

解决方案2

如果使用ReSharper,在有问题的DataContext上按Alt-Enter将弹出一个菜单,帮助您将正确的DataContext插入XAML。

我用它来正确解决问题。

enter image description here

解决方案3

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

enter image description here

解决方案4

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

enter image description here

解决方案5

DevExpress还可以使用其向导帮助您在XAML中解决此错误。

在XAML中,选择要为其设置数据上下文的父元素(通常是整个表单),然后在设计器中选择动作三角形。

然后,使用C#代码浏览到该类。

enter image description here

提示:除非您向该类添加无参数构造函数,否则该类将不可见。

之前的XAML
<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">

之后的XAML
<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>

提示6

如果您无法在WPF设计器上看到智能标记,请检查它们是否在某些时候没有关闭:

enter image description here

解决方案7

每次有绑定错误时,可以添加一个弹出消息框的snippet of code on startup。事实证明这非常有用。

如果上述网络链接出现故障,请输入以下代码:

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

方法:

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);
    }
  }
}

解决方案8

使用免费实用程序Snoop

有一个非常好的功能,允许您通过带有绑定错误的控件进行过滤。这允许您直接导航到具有绑定错误的视觉效果。

启动Snoop之后:

  1. 点击并在正在运行的应用上拖动第二个目标图标。
  2. 按住Ctrl + Shift。
  3. 当您将鼠标移动到正在运行的应用程序上时,鼠标下的任何控件都会以红色标出。
  4. 释放鼠标,Snoop将弹出一个窗口,显示可视树中的所有XAML。
  5. enter image description here

    enter image description here

    提示9 - 设计时DataContext

    实际上有两个完全独立的DataContexts:design timerun time

    以前的大多数解决方案都专注于设置run time DataContext。

    设置design time DataContext后,Visual Studio或Blend中的XAML预览将显示自定义C#类提供的自定义数据。

    如果使用Blend,也可以从XML文件中读取此自定义数据,但我更喜欢从我自己的C#类中提供它。

    要设置design time DataContext,请参阅:

    或者,将此添加到任何元素(这将在设计时新增类MyClass,因此Intellisense将起作用):

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

    这是标题:

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

    在幕后,当您设置design time DataContext:

    • Visual Studio设计器(或Blend)将自动实例化您指向它的类的新实例。如果您创建静态类,这也适用。
    • 然后,在XAML预览中,当您编辑XAML时,它将显示C#类的实时数据。
    • 这使设计变得非常快,因为您可以在设计时使用实时数据,而您无需一直运行程序来查看它的外观。

    请注意,只有在使用用户控件时才会显示XAML预览。如果您更喜欢使用DataTemplates,则没有问题:您可以创建包含DataTemplate的临时用户控件,并将design time DataContext设置为指向静态类。对静态类进行编码,以便创建ViewModel的新实例(即要绑定到的类)。例如,您的静态类可以从数据库读取数据,填充ViewModel的属性,并且您可以在XAML设计时使用数据库中的实时数据。

    这种技术也非常适用于依赖注入,例如Unity或MEF。您必须将design time DataContext指向一个静态类,该类从依赖项注入容器中获取相应的类,并设置所有内容。然后,您可以在XAML预览中的设计时查看实时数据。上述链接演示了这是如何工作的(在XAML设计时完成了直播时钟的YouTube视频!)。

    毋庸置疑,这种技术与MVVM模式以及MVVM +依赖注入完美配合。对于那些不熟悉MVVM的人来说,它是制作优雅,干净,可维护且易于改变的项目的好方法。 Microsoft Blend本身完全使用MVVM模式编写。