Ustawienie czasu projektowania DataContext w oknie powoduje błąd kompilatora?

203

Mam następujący XAML poniżej dla głównego okna w mojej aplikacji WPF, próbuję ustawić czas projektowania d:DataContextponiżej, co mogę z powodzeniem zrobić dla wszystkich moich różnych UserControl, ale daje mi ten błąd, gdy próbuję to zrobić na okno...

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
źródło

Odpowiedzi:

263

Musiałem dodać mc:Ignorable="d"atrybut do znacznika Window. Zasadniczo nauczyłem się czegoś nowego. d:Prefiks namespace że Expression Blend / Visual Studio projektant przyznaje faktycznie ignorowane / „wypowiedziało się” przez prawdziwego kompilatora / XAML parser!

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

Poniższe wzięto z

Nathan, Adam (2010-06-04). WPF 4 Unleashed (lokalizacje Kindle 1799-1811). Sams Wersja Kindle.

Zgodność znaczników

Przestrzeń nazw XML kompatybilności ze znacznikami ( http://schemas.openxmlformats.org/markup-compatibility/2006 , zwykle używana z mcprzedrostkiem) zawiera atrybut Ignorable, który instruuje procesory XAML, aby ignorowały wszystkie elementy / atrybuty w określonych przestrzeniach nazw, jeśli nie mogą być rozstrzygane na ich typy / członków .NET. (Przestrzeń nazw ma również atrybut ProcessContent, który zastępuje Ignorable dla określonych typów w ignorowanych przestrzeniach nazw).

Expression Blend korzysta z tej funkcji, aby np. Dodawać właściwości w czasie projektowania do zawartości XAML, które można zignorować w czasie wykonywania.

mc:Ignorablemoże otrzymać rozdzieloną spacją listę przestrzeni nazw, a mc: ProcessContent może otrzymać rozdzieloną spacją listę elementów. Gdy XamlXmlReader napotyka ignorowalną zawartość, której nie można rozwiązać, nie zgłasza za nią żadnych węzłów. Jeśli niemożliwe do usunięcia treści można rozwiązać, zostaną zgłoszone normalnie. Dlatego konsumenci nie muszą robić nic specjalnego, aby poprawnie obsługiwać zgodność znaczników.

Jon Erickson
źródło
12
Od jakiegoś czasu biję się z tym głową. Ma to sens, ale wydaje się ogromnym niedopatrzeniem (obiekty danych w czasie projektowania powinny być obsługiwane bez tych wszystkich włamań)
Basic
3
Jeśli zamiast tego chcesz użyć niezauważalnego kontekstu danych w jego własnym węźle, użyj <d: Window.DataContext />
ChéDon
Świetna wskazówka, pomogła mi w walce z dziwnym wyjątkiem kompilatora. Bez mc: ignorable, nawet jeśli ustawię d: DataContext, kompilator XAML zinterpretował to jako próbę ustawienia DataContext i narzekał na użycie niewłaściwej przestrzeni nazw xmlns.
Tore Aurstad
19

Wow, co za ból! Miejmy nadzieję, że MS wprowadzi wsparcie dla x: Bind w czasie projektowania VS.

Możemy korzystać z projektanta VS, ale także łatwo przełączać się na x: Bind zamiast Binding. Oto co zrobiłem:

  • W moim widoku dodałem właściwość, aby uzyskać mój ViewModel. Ma to sens, ponieważ ścieżki x: Bind są względne względem strony (tj. Obiektu View).

  • Na mojej stronie XAML dodałem następujące elementy <Page ... >na górze XAML:

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

W ten sposób rzeczywisty kontekst danych strony jest ustawiany na samą stronę ze względu na {x:Bind}. To dlatego, że x:Bindjest względny do strony i nie podano żadnej ścieżki.

Jednocześnie, ze względu na d:DataContextlinię, projektant VS zastanawia się nad klasą MyView (bez tworzenia instancji) na potrzeby interakcji projektanta VS. Umożliwia to projektowanie VS z MyView, gdzie można przewinąć w dół do właściwości ViewModel, rozwinąć ją i wybrać element, z którym chcesz się połączyć.

Kiedy to wszystko zrobisz, projektant VS utworzy instrukcję Binding, której ścieżka jest względna w stosunku do widoku, tzn. Jest dokładnie taka sama, jak ścieżka oczekiwana przez x: Bind. Tak więc, jeśli chcesz przełączyć się na x: Bind później, możesz po prostu wyszukać i zastąpić wszystkie „ {Binding” „ {x:Bind” „ ”.

Dlaczego potrzebujemy d:DataContextlinii, aby powiedzieć VS, na którą klasę patrzeć? Dobre pytanie, ponieważ można by pomyśleć, że VS może dowiedzieć się, że następny wiersz ustawia DataContext na stronę, używając DataContext={x:Bind}. Śmiało, spróbuj, to nie działa i nie działa, jeśli zmienisz x: Bind na Binding w stosunku do siebie.

Mam nadzieję, że ta sytuacja zostanie oczyszczona przez stwardnienie rozsiane !!

sjb -
źródło
3
WPF nie obsługuje x: Bind; ta odpowiedź nie zadziała dla OP.
Byrel Mitchell,