Visual Studio 2012でWPF + XAML + MVVMを使用すると、このエラーが発生します。
DataContextが不明なため、シンボル「MyVariable」を解決できません
解決策は何ですか?
このエラーは、WPF用のXAMLを設計するときにReSharperによって生成され、XAMLがランタイムバインディングを含むクラスを見つけることができないことを示します。これは通常、DataContext
が正しく設定されていないことを示しています。
このエラーは次のことを意味します。
binding
をCtrlキーを押しながらクリックして、設計時にXAMLからC#クラスに自動的に移動することはできません。MVVMで考える人にとって、このエラーは、ビューがViewModelを見つけられないことを示しています。
DataBindingの仕組みを理解するために、ある種のWebチュートリアルをご覧ください。推奨 Microsoftデータバインディングの概要 。
ReSharperを使用している場合、問題のDataContextでAlt-Enterを押すと、XAMLに正しいDataContextを挿入するのに役立つメニューが表示されます。
これを使用して、問題を正しく解決しました。
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">
<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>
WPFデザイナーでスマートタグが表示されない場合は、ある時点でオフになっていないことを確認してください。
バインドエラーが発生するたびにメッセージボックスをポップアップ表示する 起動時のコードのスニペット を追加できます。これは非常に有用であることが判明しました。
前述のWebリンクがダウンした場合のコードは次のとおりです。
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);
}
}
}
無料のユーティリティ Snoop を使用します。
バインディングエラーのあるコントロールでフィルタリングできる、本当に素晴らしい機能があります。これにより、バインドエラーのあるビジュアルに直接移動できます。
Snoopを起動した後:
実際には、design time
とrun time
の2つの完全に独立したDataContextがあります。
これまでのソリューションのほとんどは、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を設定すると、舞台裏で:
XAMLプレビューは、ユーザーコントロールを使用している場合にのみ表示されることに注意してください。 DataTemplatesを使用する場合は、問題ありません。DataTemplateを含む一時的なユーザーコントロールを作成し、design time
DataContextを静的クラスを指すように設定できます。静的クラスをコーディングして、ViewModelの新しいインスタンス(つまり、バインドするクラス)を作成します。たとえば、静的クラスはデータベースからデータを読み取り、ViewModelのプロパティを設定し、XAML設計時にデータベースのライブデータを操作できます。
この手法は、UnityやMEFなどの依存性注入でも完全に機能します。 design time
DataContextを、依存関係注入コンテナーから適切なクラスを取得し、すべてをセットアップする静的クラスに向ける必要があります。その後、設計時にXAMLプレビューでライブデータを確認できます。前述のリンクは、これがどのように機能するかをデモします(XAML設計時のライブティッククロックのYouTubeビデオで完了します!)。
言うまでもなく、この手法はMVVMパターン、およびMVVM + Dependency Injectionでも完全に機能します。 MVVMになじみのない人にとっては、MVVMは、エレガントで、クリーンで、保守しやすく、変更しやすいプロジェクトを作成するための優れた方法です。 Microsoft Blend自体は、MVVMパターンを使用して完全に記述されています。