0
votes

In WPF model binding could be achieved by placing a DataTemplate with the viewmodel and view types in your app.xaml. You could then just bind a viewmodel to a contentpresenter and your view would change if you changed your view model through some kind of event.

Here's the old code:

App.xaml (AView and BView are just user controls)

<Application.Resources>
    <DataTemplate DataType="{x:Type viewModels:AViewModel}">
        <views:ViewA/>
    </DataTemplate>
    <DataTemplate DataType="{x:Type viewModels:BViewModel}">
        <views:ViewB/>
    </DataTemplate>
</Application.Resources>

Then on some kind of child view that contained the current context:

<ContentPresenter Content="{Binding CurrentViewModel}" />

(Much like https://stackoverflow.com/a/22376718/82333)

However datatemplate syntax no longer works. I've read up on x:bind, but doing a basic replace to the viewmodel type doesn't fix it.

Using this syntax:

<Application.Resources>
    <DataTemplate x:Key="ViewAKey" x:DataType="viewModels:AViewModel">
        <views:ViewA/>
    </DataTemplate>
    <DataTemplate x:Key="ViewBKey" x:DataType="viewModels:BViewModel">
        <views:ViewB/>
    </DataTemplate>
</Application.Resources>

Causes several errors:

Visual studio complains that the view models are not in the namespaces I supplied.

XBF generation error code 0x09c4.

What is the equivalent syntax for this operation in Windows 10 Universal Apps?

1
Well I had a windows 8.1 wpf app that was working then I moved the code over to a windows 10 universal app and the Application.Resources was no longer valid and I was receiving strange error messages. - C Bauer
If there is no DataTemplate what is type of ContentTemplate property? - Maximus

1 Answers

4
votes

In WPF, the DataType is a dependency property which can be retrieved in runtime.

In UWP, the x:DataType is compile-time property, you cannot get the value in runtime. x:DataType is working with {x:Bind}. While using x:DataType in Application.Resources, it will raise XBF generation error as compiler can't generate code. {x:Bind} depends on code generation, if you use {x:Bind} in a resource dictionary, the resource dictionary needs to have a code-behind class. And then you can re-use the resource dictionary by instantiating its type instead of referencing its filename. For more information about how to use {x:Bind} in a resource dictionary, see Resource dictionaries with {x:Bind}.

If we need to switch the DataTemplate based on the model type, we need to use DataTemplateSelector class.

See the similar case: How to associate view with viewmodel or multiple DataTemplates for ViewModel? for a sample about how to map the data type and data template in UWP through DataTemplateSelector.