Je rencontre cette erreur lors de l'utilisation de WPF + XAML + MVVM dans Visual Studio 2012.
Impossible de résoudre le symbole "MyVariable" en raison de DataContext inconnu
Quelle est la solution?
Cette erreur est produite par ReSharper lors de la conception de XAML pour WPF et indique que le XAML ne peut pas trouver la classe qui contient des liaisons au moment de l'exécution. Cela indique généralement que DataContext
n'est pas défini correctement.
Cette erreur signifie que:
binding
dans le XAML;Pour ceux d'entre nous qui pensent dans MVVM, cette erreur indique que la vue ne peut pas trouver le ViewModel.
Parcourez une sorte de didacticiel Web pour comprendre le fonctionnement de DataBinding. Recommander Microsoft Data Binding Overview .
Si vous utilisez ReSharper, appuyer sur Alt-Entrée sur le DataContext incriminé fera apparaître un menu qui vous aidera à insérer le DataContext correct dans votre XAML.
J'ai utilisé cela pour résoudre correctement le problème.
Dans le volet "Propriétés" de Visual Studio, vous pouvez sélectionner le contexte de données pour le contrôle sélectionné:
Le mélange peut également être utilisé pour définir le contexte des données. Ouvrez votre fichier .sln dans Blend, sélectionnez l'élément de conception, puis dans les propriétés sélectionnez "Nouveau":
DevExpress peut également vous aider à résoudre cette erreur dans le XAML à l'aide de son assistant.
Dans le XAML, sélectionnez l'élément parent pour lequel vous souhaitez définir le contexte de données (généralement le formulaire entier), puis dans le concepteur, sélectionnez le triangle d'action.
Ensuite, accédez à la classe avec le code C #.
Astuce: La classe sera invisible sauf si vous ajoutez un constructeur sans paramètre à la classe.
<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>
Si vous ne pouvez pas voir les balises actives sur le concepteur WPF, vérifiez qu’elles n’ont pas été désactivées à un moment donné:
On peut ajouter appeler un extrait de code au démarrage qui apparaît une boîte de message chaque fois qu'il y a une erreur de liaison. Cela s'est avéré très utile.
Dans le cas où le lien Web susmentionné tombe en panne, voici le code:
public partial class Window1 : Window
{
public Window1()
{
BindingErrorTraceListener.SetTrace();
InitializeComponent();
}
}
Méthode:
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);
}
}
}
Utilisez l'utilitaire gratuit Snoop .
Il y a une fonctionnalité vraiment sympa qui vous permet de filtrer par des contrôles avec des erreurs de liaison. Cela vous permet de naviguer directement vers le visuel avec l'erreur de liaison.
Après avoir démarré Snoop:
Il existe en fait deux DataContexts complètement distincts: design time
et run time
.
La plupart des solutions précédentes visent à définir le run time
DataContext.
Une fois que vous avez défini le design time
DataContext, l'aperçu XAML dans Visual Studio ou Blend affichera les données personnalisées fournies par votre classe C # personnalisée.
Si vous utilisez Blend, ces données personnalisées peuvent également être lues à partir d'un fichier XML, mais je préfère les fournir à partir de ma propre classe C #.
Pour définir le design time
DataContext, voir:
Ou, ajoutez ceci à n'importe quel élément (cela va créer une nouvelle classe MyClass
au moment du design, donc Intellisense fonctionnera):
d:DataContext="{d:DesignInstance d:Type=viewModel:MyClass, IsDesignTimeCreatable=True}"
Et ceci à l'en-tête:
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.Microsoft.com/expression/blend/2008"
mc:Ignorable="d"
Dans les coulisses, lorsque vous définissez le design time
DataContext:
Notez que l'aperçu XAML apparaît uniquement si vous utilisez un contrôle utilisateur. Si vous préférez utiliser des modèles de données, pas de problème: vous pouvez créer un contrôle utilisateur temporaire qui inclut le modèle de données et définir le design time
DataContext pour pointer sur une classe statique. Codez la classe statique afin qu'elle crée une nouvelle instance de votre ViewModel (c'est-à-dire la classe à laquelle vous souhaitez vous lier). Par exemple, votre classe statique pourrait lire les données d'une base de données, remplir les propriétés du ViewModel et vous pourriez travailler avec des données en direct de la base de données au moment de la conception XAML.
Cette technique fonctionne également parfaitement avec l'injection de dépendance, comme Unity ou MEF. Vous devez pointer votre design time
DataContext à une classe statique qui récupère les classes appropriées du conteneur d'injection de dépendances et configure tout. Vous pouvez ensuite voir les données en direct au moment de la conception dans l'aperçu XAML. Les liens susmentionnés montrent comment cela fonctionne (avec des vidéos YouTube d'une horloge en direct au moment de la conception XAML!).
Inutile de dire que cette technique fonctionne parfaitement avec le modèle MVVM, ainsi qu'avec MVVM + Dependency Injection. Pour ceux d'entre vous qui ne connaissent pas MVVM, c'est un excellent moyen de produire des projets élégants, propres, maintenables et faciles à modifier. Microsoft Blend lui-même est entièrement écrit en utilisant le modèle MVVM.