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

Posted

技术标签:

【中文标题】ReSharper WPF 错误:“由于未知 DataContext,无法解析符号“MyVariable””【英文标题】:ReSharper WPF error: "Cannot resolve symbol "MyVariable" due to unknown DataContext" 【发布时间】:2014-10-22 09:02:00 【问题描述】:

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

由于未知数据上下文,无法解析符号“MyVariable”

解决办法是什么?

【问题讨论】:

这个问题符合网站的规则:如果任何用户遇到这个特定的错误消息,那么他们可以谷歌它找到解决这个错误的步骤。这对包括我自己在内的其他读者很有用(这个错误非常棘手,我花了一段时间才解决)。 恕我直言,问题主体确实缺乏。经过进一步审查,我将部分标题编辑到正文中并投票重新打开。 【参考方案1】:

此错误是 ReSharper 在为 WPF 设计 XAML 时产生的,表示 XAML 找不到包含运行时绑定的类。这通常表示DataContext 设置不正确。

这个错误意味着:

Intellisense for XAML 在设计时无法正常工作; 无法在设计时使用 Ctrl 键单击 XAML 中的 binding,从 XAML 自动导航到 C# 类; 当我们在属性上选择“查找用法”时,它不会显示 XAML 和 C# 中的用法; 设计器不能显示来自自定义 C# 类的实时数据。

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

解决方案 1

通过某种网络教程来了解 DataBinding 的工作原理。推荐Microsoft Data Binding Overview。

解决方案 2

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

我用它来正确解决问题。

解决方案 3

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

解决方案 4

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

解决方案 5

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

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

然后,浏览到带有 C# 代码的类。

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

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 设计器上看不到智能标记,请检查它们是否在某个时候被关闭:

解决方案 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 后:

    单击第二个目标图标并将其拖动到正在运行的应用程序上方。 按住 Ctrl + Shift。 当您将鼠标移到正在运行的应用程序上时,鼠标下方的任何控件都将显示为红色。 松开鼠标,Snoop 将弹出一个窗口,在可视化树中显示所有 XAML。

提示 9 - 设计时数据上下文

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

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

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

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

要设置design time DataContext,请参见:

Adam Prescott: Design-Time Data Binding in WPF See UI changes in design view with WPF & XAML and data binding?

或者,将其添加到任何元素(这将在设计时添加 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 模式编写。

【讨论】:

以上是关于ReSharper WPF 错误:“由于未知 DataContext,无法解析符号“MyVariable””的主要内容,如果未能解决你的问题,请参考以下文章

ReSharper智能感知指向错误的功能

ReSharper智能感知指向错误的功能

解决 C# 中的 Resharper 错误

将 Resharper 忽略的错误置于版本控制之下

ReSharper 声称我的表达总是正确的?它是正确的还是一个错误?

VS2010 中的 ReSharper 8.0 调试插件第一次工作,然后错误后续尝试