La définition de DataContext au moment de la conception donne une erreur de compilation?

203

J'ai le XAML suivant ci-dessous pour la fenêtre principale de mon application WPF, j'essaie de définir le temps de conception d:DataContext dessous, ce que je peux faire avec succès pour tous mes divers UserControls, mais cela me donne cette erreur lorsque j'essaie de le faire sur le la fenêtre...

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

Réponses:

263

J'avais besoin d'ajouter l' mc:Ignorable="d"attribut à la balise Window. J'ai essentiellement appris quelque chose de nouveau. Le d:préfixe d'espace de noms reconnu par Expression Blend / Visual Studio Designer est en fait ignoré / "mis en commentaire" par le vrai compilateur / analyseur xaml!

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

Ce qui suit est tiré de

Nathan, Adam (2010-06-04). WPF 4 Unleashed (Emplacements Kindle 1799-1811). Sams. Édition Kindle.

Compatibilité des balises

L'espace de noms XML de compatibilité de balisage ( http://schemas.openxmlformats.org/markup-compatibility/2006 , généralement utilisé avec unmc préfixe) contient un attribut Ignorable qui demande aux processeurs XAML d'ignorer tous les éléments / attributs dans les espaces de noms spécifiés s'ils ne peuvent pas être résolus à leurs types / membres .NET. (L'espace de noms possède également un attribut ProcessContent qui remplace Ignorable pour des types spécifiques à l'intérieur des espaces de noms ignorés.)

Expression Blend tire parti de cette fonctionnalité pour ajouter des propriétés au moment de la conception au contenu XAML qui peuvent être ignorées lors de l'exécution.

mc:Ignorablepeut recevoir une liste d'espaces de noms séparés par des espaces, et mc: ProcessContent peut recevoir une liste d'éléments séparés par des espaces. Lorsque XamlXmlReader rencontre du contenu ignorable qui ne peut pas être résolu, il ne signale aucun nœud pour lui. Si le contenu ignorable peut être résolu, il sera signalé normalement. Les consommateurs n'ont donc rien à faire de spécial pour gérer correctement la compatibilité des balises.

Jon Erickson
la source
12
Je me suis battu la tête contre cela depuis un certain temps. Cela a du sens mais semble être une énorme erreur (les objets de données au moment du design devraient être pris en charge sans tous ces hacks)
Basic
3
Si vous voulez plutôt un contexte de données ignorable dans son propre nœud comme attribut, utilisez <d: Window.DataContext />
ChéDon
Excellent conseil, m'a aidé à lutter avec une étrange exception du compilateur. Sans mc: ignorable, même si j'ai défini d: DataContext, le compilateur XAML l'a interprété comme essayant de définir DataContext et s'est plaint d'utiliser le mauvais espace de noms xmlns.
Tore Aurstad
19

Wow, quelle douleur! Espérons que MS propose une prise en charge VS au moment de la conception pour x: Bind.

Nous pourrons utiliser le concepteur VS mais aussi pouvoir basculer facilement vers x: Bind au lieu de Binding. Voici ce que j'ai fait:

  • Dans ma vue, j'ai ajouté une propriété pour obtenir mon ViewModel. Cela est logique car les chemins x: Bind sont relatifs à la page (c'est-à-dire l'objet View).

  • Dans ma page XAML, j'ai ajouté ce qui suit en <Page ... >haut de la XAML:

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

De cette façon, le contexte de données réel de la page est défini sur la page elle-même en raison de la {x:Bind}. C'est parce que x:Bindc'est relatif à la page et il n'y a pas de chemin donné.

En même temps, en raison de la d:DataContextligne, le concepteur VS réfléchit sur la classe MyView (sans créer d'instance) aux fins de l'interaction du concepteur VS. Cela permet à VS design de MyView, où vous pouvez ensuite faire défiler jusqu'à la propriété ViewModel, la développer et sélectionner l'élément auquel vous souhaitez vous lier.

Lorsque vous faites tout cela, le concepteur VS crée une instruction Binding dont le chemin est relatif à la vue, c'est-à-dire qu'il se trouve être exactement le même que le chemin que x: Bind attend. Donc, si vous souhaitez passer à x: Bind plus tard, vous pouvez simplement rechercher et remplacer tous les " {Binding" par " {x:Bind".

Pourquoi avons-nous même besoin de la d:DataContextligne pour dire à VS quelle classe regarder? Bonne question, car vous penseriez que VS pourrait comprendre que la ligne suivante définit le DataContext sur la page, en utilisant DataContext={x:Bind}. Allez-y et essayez-le, cela ne fonctionne pas et cela ne fonctionne pas non plus si vous changez x: Bind en Binding par rapport à self.

Espérons que cette situation sera nettoyée par MS !!

sjb -
la source
3
WPF ne prend pas en charge x: Bind; cette réponse ne fonctionnera pas pour OP.
Byrel Mitchell