Festlegen der Entwurfszeit DataContext in einem Fenster gibt einen Compilerfehler aus?

203

Ich habe die folgende XAML unten für das Hauptfenster in meiner WPF-Anwendung. Ich versuche, die Entwurfszeit d:DataContextunten festzulegen, die ich für alle meine verschiedenen UserControls erfolgreich ausführen kann, aber es gibt mir diesen Fehler, wenn ich versuche, dies auf der zu tun Fenster...

Error 1 The property 'DataContext' must be in the default namespace or in the element namespace 'http://schemas.microsoft.com/winfx/2006/xaml/presentation'. Line 8 Position 9. C:\dev\bplus\PMT\src\UI\MainWindow.xaml 8 9 UI

<Window x:Class="BenchmarkPlus.PMT.UI.MainWindow"
    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:UI="clr-namespace:BenchmarkPlus.PMT.UI"
    xmlns:Controls="clr-namespace:BenchmarkPlus.PMT.UI.Controls"
    d:DataContext="{d:DesignInstance Type=UI:MainViewModel, IsDesignTimeCreatable=True}"
    Title="MainWindow" Height="1000" Width="1600" Background="#FF7A7C82">

    <Grid>
        <!-- Content Here -->
    </grid>

</Window>
Jon Erickson
quelle

Antworten:

263

Ich musste das mc:Ignorable="d"Attribut zum Window-Tag hinzufügen . Im Wesentlichen habe ich etwas Neues gelernt. Das d:Namespace-Präfix, das der Designer von Expression Blend / Visual Studio bestätigt, wird vom echten Compiler / xaml-Parser tatsächlich ignoriert / " auskommentiert"!

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

Folgendes wurde entnommen

Nathan, Adam (04.06.2010). WPF 4 entfesselt (Kindle Locations 1799-1811). Sams. Kindle Edition.

Markup-Kompatibilität

Der XML-Namespace für Markup-Kompatibilität ( http://schemas.openxmlformats.org/markup-compatibility/2006 , normalerweise mit einem mcPräfix verwendet) enthält ein Attribut Ignorable, das XAML-Prozessoren anweist, alle Elemente / Attribute in angegebenen Namespaces zu ignorieren, wenn dies nicht möglich ist in ihre .NET-Typen / Mitglieder aufgelöst werden. (Der Namespace verfügt außerdem über ein ProcessContent-Attribut, das Ignorable für bestimmte Typen in den ignorierten Namespaces überschreibt.)

Expression Blend nutzt diese Funktion, um beispielsweise XAML-Inhalten Design-Time-Eigenschaften hinzuzufügen, die zur Laufzeit ignoriert werden können.

mc:Ignorablekann eine durch Leerzeichen getrennte Liste von Namespaces erhalten, und mc: ProcessContent kann eine durch Leerzeichen getrennte Liste von Elementen erhalten. Wenn XamlXmlReader auf ignorierbaren Inhalt stößt, der nicht aufgelöst werden kann, werden keine Knoten dafür gemeldet. Wenn der ignorierbare Inhalt behoben werden kann, wird er normal gemeldet. Die Verbraucher müssen also nichts Besonderes tun, um die Markup-Kompatibilität korrekt zu handhaben.

Jon Erickson
quelle
12
Ich habe schon seit einiger Zeit meinen Kopf dagegen geschlagen. Sinnvoll, scheint aber ein großes Versehen zu sein (Datenobjekte zur Entwurfszeit sollten ohne all diese Hacks unterstützt werden)
Basic
3
Wenn Sie stattdessen einen ignorierbaren Datenkontext in einem eigenen Knoten als Attribut wünschen, verwenden Sie <d: Window.DataContext />
ChéDon
Toller Tipp, hat mir geholfen, mich mit einer seltsamen Compiler-Ausnahme zu bemühen. Ohne mc: ignorable hat der XAML-Compiler, selbst wenn ich d: DataContext festgelegt habe, dies als Versuch interpretiert, DataContext festzulegen, und sich über die Verwendung des falschen xmlns-Namespace beschwert.
Tore Aurstad
19

Wow, was für ein Schmerz! Hoffen wir, dass MS x: Bind in VS-Design-Zeit unterstützt.

Wir können den VS-Designer verwenden, aber auch einfach zu x: Bind anstatt Binding wechseln. Folgendes habe ich getan:

  • In meiner Ansicht habe ich eine Eigenschaft hinzugefügt, um mein ViewModel abzurufen. Dies ist sinnvoll, da x: Bindungspfade relativ zur Seite (dh zum View-Objekt) sind.

  • In meiner Seite XAML habe ich <Page ... >oben in der XAML Folgendes hinzugefügt :

    mc:Ignorable="d" 
    d:DataContext="{d:DesignInstance Type=local:MyView, IsDesignTimeCreatable=False}" 
    DataContext="{x:Bind}"

Auf diese Weise wird der tatsächliche Datenkontext der Seite aufgrund der auf die Seite selbst festgelegt {x:Bind}. Das liegt daran, dass x:Bindes relativ zur Seite ist und kein Pfad angegeben ist.

Gleichzeitig d:DataContextreflektiert der VS-Designer aufgrund der Linie die MyView-Klasse (ohne eine Instanz zu erstellen) zum Zweck der VS-Designer-Interaktion. Auf diese Weise können Sie VS-Designs in MyView entwerfen, wo Sie dann zur ViewModel-Eigenschaft scrollen, sie erweitern und das Element auswählen können, an das Sie binden möchten.

Wenn Sie dies alles tun, erstellt der VS-Designer eine Bindungsanweisung, deren Pfad relativ zur Ansicht ist, dh genau der Pfad, den x: Bind erwartet. Wenn Sie später zu x: Bind wechseln möchten, können Sie einfach alle " {Binding" durch " {x:Bind" suchen und ersetzen .

Warum brauchen wir überhaupt die d:DataContextZeile, um VS mitzuteilen, welche Klasse wir betrachten sollen? Gute Frage, da Sie denken würden, dass VS in der nächsten Zeile herausfinden könnte, dass der DataContext mithilfe von auf die Seite gesetzt wird DataContext={x:Bind}. Probieren Sie es aus, es funktioniert nicht und es funktioniert auch nicht, wenn Sie x: Bind to Binding relativ zu self ändern.

Hoffentlich wird diese Situation von MS aufgeräumt !!

sjb -
quelle
3
WPF unterstützt x: Bind nicht. Diese Antwort funktioniert nicht für OP.
Byrel Mitchell