Mengatur waktu desain DataContext pada Window memberikan kesalahan kompilator?

203

Saya memiliki XAML berikut di bawah ini untuk jendela utama dalam aplikasi WPF saya, saya mencoba untuk mengatur waktu desain di d:DataContextbawah ini, yang saya dapat berhasil lakukan untuk semua berbagai UserControls saya, tetapi itu memberi saya kesalahan ini ketika saya mencoba untuk melakukannya pada jendela...

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
sumber

Jawaban:

263

Saya perlu menambahkan mc:Ignorable="d"atribut ke tag Window. Pada dasarnya saya belajar sesuatu yang baru. The d:namespace prefix yang Expression Blend / Visual desainer Studio mengakui sebenarnya diabaikan / "komentar" oleh compiler nyata / XAML parser!

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

Berikut ini diambil dari

Nathan, Adam (2010-06-04). WPF 4 Unleashed (Lokasi Kindle 1799-1811). Sams. Edisi menyalakan.

Kompatibilitas Markup

XML namespace kompatibilitas markup ( http://schemas.openxmlformats.org/markup-compatibility/2006 , biasanya digunakan dengan mcawalan) berisi atribut Ignorable yang memerintahkan prosesor XAML untuk mengabaikan semua elemen / atribut dalam ruang nama tertentu jika mereka tidak bisa diselesaikan ke tipe / anggota .NET mereka. (Namespace juga memiliki atribut ProcessContent yang menimpa Ignorable untuk jenis tertentu di dalam ruang nama yang diabaikan.)

Expression Blend memanfaatkan fitur ini untuk melakukan hal-hal seperti menambahkan properti desain-waktu ke konten XAML yang dapat diabaikan saat runtime.

mc:Ignorabledapat diberi daftar ruang nama yang dibatasi ruang, dan mc: ProcessContent dapat diberi daftar elemen yang dibatasi ruang. Ketika XamlXmlReader menemukan konten yang tidak dapat dipecahkan yang tidak dapat diselesaikan, itu tidak melaporkan node untuk itu. Jika konten yang dapat diabaikan dapat diselesaikan, itu akan dilaporkan secara normal. Jadi konsumen tidak perlu melakukan sesuatu yang khusus untuk menangani kompatibilitas markup dengan benar.

Jon Erickson
sumber
12
Saya telah memukuli kepala saya terhadap ini selama beberapa waktu. Masuk akal tetapi tampaknya seperti pengawasan besar (objek data desain-waktu harus didukung tanpa semua peretasan ini)
Basic
3
Jika Anda ingin konteks data yang dapat diabaikan dalam simpulnya sendiri sebagai atribut gunakan <d: Window.DataContext />
ChéDon
Great tip, membantu saya keluar berjuang dengan pengecualian kompiler aneh. Tanpa mc: ignorable, bahkan jika saya menetapkan d: DataContext, kompiler XAML menafsirkannya sebagai mencoba untuk mengatur DataContext dan mengeluh tentang menggunakan namespace xmlns yang salah.
Tore Aurstad
19

Wow, sungguh menyebalkan! Mari berharap MS memberikan dukungan waktu desain VS untuk x: Bind.

Kami dapat menggunakan perancang VS tetapi juga dapat beralih dengan mudah ke x: Bind bukan Binding. Inilah yang saya lakukan:

  • Di View saya, saya menambahkan properti untuk mendapatkan ViewModel saya. Ini masuk akal karena x: Bind path relatif terhadap Halaman (yaitu objek View).

  • Di Halaman XAML saya, saya menambahkan yang berikut ke <Page ... >bagian atas XAML:

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

Dengan cara ini, konteks data aktual Halaman diatur ke Halaman itu sendiri karena {x:Bind}. Itu karena x:Bindrelatif terhadap Halaman dan tidak ada jalur yang diberikan.

Pada saat yang sama, karena d:DataContextgaris, perancang VS merefleksikan kelas MyView (tanpa membuat instance) untuk tujuan interaksi perancang VS. Ini memungkinkan VS desain dari MyView, di mana Anda kemudian dapat menggulir ke bawah ke properti ViewModel, memperluasnya dan memilih item yang ingin Anda ikat.

Ketika Anda melakukan semua itu, perancang VS akan membuat pernyataan Binding yang jalurnya relatif terhadap tampilan, yaitu kebetulan persis sama dengan jalur yang x: Bind harapkan. Jadi, jika Anda ingin beralih ke x: Bind nanti, Anda bisa mencari dan mengganti semua " {Binding" dengan " {x:Bind".

Mengapa kita bahkan perlu d:DataContextgaris untuk memberi tahu VS kelas apa yang harus dilihat? Pertanyaan yang bagus, karena Anda akan berpikir bahwa VS bisa mengetahui baris selanjutnya yang menetapkan DataContext ke Halaman, menggunakan DataContext={x:Bind}. Silakan dan coba, itu tidak berhasil dan juga tidak berfungsi jika Anda mengubah x: Bind ke Binding relatif terhadap diri.

Semoga situasi ini akan dibersihkan oleh MS !!

sjb -
sumber
3
WPF tidak mendukung x: Bind; jawaban ini tidak akan berfungsi untuk OP.
Byrel Mitchell