ReSharper WPF 错误:“无法解析符号“MyVariable"由于未知的 DataContext" [英] ReSharper WPF error: "Cannot resolve symbol "MyVariable" due to unknown DataContext"

查看:29
本文介绍了ReSharper WPF 错误:“无法解析符号“MyVariable"由于未知的 DataContext"的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

<块引用>

由于未知的 DataContext 无法解析符号MyVariable"

解决办法是什么?

解决方案

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

这个错误意味着:

  • XAML 的智能感知在设计时效果不佳;
  • 不能在设计时使用 Ctrl-单击 XAML 中的 binding 自动从 XAML 导航到 C# 类;
  • 当我们选择Find Usages"时在属性上,它不会显示 XAML 和 C# 中的用法;
  • 设计器不能不显示来自自定义 C# 类的实时数据.

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

解决方案 1

通过某种网络教程来了解数据绑定的工作原理.推荐 每次出现绑定错误时都会弹出一个消息框.结果证明这非常有用.

如果上述网页链接失效,代码如下:

public 部分类 Window1 : Window{公共窗口 1(){BindingErrorTraceListener.SetTrace();初始化组件();}}

方法:

使用 System.Diagnostics;使用 System.Text;使用 System.Windows;命名空间 SOTC_BindingErrorTracer{公共类 BindingErrorTraceListener : DefaultTraceListener{私有静态 BindingErrorTraceListener _Listener;公共静态无效 SetTrace(){ SetTrace(SourceLevels.Error, TraceOptions.None);}public static void SetTrace(SourceLevels 级别,TraceOptions 选项){if (_Listener == null){_Listener = new BindingErrorTraceListener();PresentationTraceSources.DataBindingSource.Listeners.Add(_Listener);}_Listener.TraceOutputOptions = 选项;PresentationTraceSources.DataBindingSource.Switch.Level = level;}public static void CloseTrace(){if (_Listener == null){ 返回;}_Listener.Flush();_Listener.Close();PresentationTraceSources.DataBindingSource.Listeners.Remove(_Listener);_监听器 = 空;}私人 StringBuilder _Message = 新 StringBuilder();私有 BindingErrorTraceListener(){ }公共覆盖无效写入(字符串消息){ _Message.Append(message);}公共覆盖无效WriteLine(字符串消息){_Message.Append(message);var final = _Message.ToString();_Message.Length = 0;MessageBox.Show(final, 绑定错误", MessageBoxButton.OK,MessageBoxImage.Error);}}}

解决方案 8

使用免费实用程序

  • 查看 UI 更改使用 WPF & 设计视图XAML 和数据绑定?
  • 或者,将其添加到任何元素(这将在设计时更新 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 预览中查看实时数据.上述链接演示了这是如何工作的(完整的 YouTube 视频包含 XAML 设计时的实时滴答时钟!).

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

    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:

    • Intellisense for XAML does not work as well at design time;
    • One cannot auto navigate from the XAML to the C# class at design time using a Ctrl-Click on the binding in the XAML;
    • When we select "Find Usages" on a property, it will not bring up the usages in the XAML as well as the C#;
    • The designer cannot not show live data from a custom C# class.

    For those of us that think in MVVM, this error indicates that the View cannot find the ViewModel.

    Solution 1

    Go through some sort of web tutorial to understand how DataBinding works. Recommend Microsoft Data Binding Overview.

    Solution 2

    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.

    Solution 3

    In the "Properties" pane of Visual Studio, you can select the data context for the selected control:

    Solution 4

    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":

    Solution 5

    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.

    XAML before

    <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 after

    <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>
    

    Hint 6

    If you cannot see the Smart Tags on the WPF designer, check that they have not been switched off at some point:

    Solution 7

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

    Solution 8

    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:

    1. Click and drag the second target icon over your running app.
    2. Hold down Ctrl + Shift.
    3. As you move your mouse over the running app, whatever control is under the mouse will then be outlined in red.
    4. Release the mouse, and Snoop will pop up a window that shows all of the XAML in the visual tree.

    Hint 9 - Design Time DataContext

    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:

    • Visual Studio designer (or Blend) will automatically instantiate a new instance of the class you point it at. This also works if you create a static class.
    • Then, in the XAML preview, as you are editing the XAML, it will display live data from your C# class.
    • This makes designing really fast, as you can work with live data at design time, and you dont have to run the program all the time to see how it looks.

    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.

    这篇关于ReSharper WPF 错误:“无法解析符号“MyVariable"由于未知的 DataContext"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆