Implementing own ViewModelLocator

1.7k Views Asked by At

I wanted to implement ViewModelLocator by my own. So I implemented the simplest app in the world. I did everything as in this tutorial. But I'm still getting an exception:

XamlParseException occured

Exception thrown: 'System.Windows.Markup.XamlParseException' in PresentationFramework.dll

Additional information: 'Provide value on 'System.Windows.StaticResourceExtension' threw an exception.' Line number '8' and line position '9'.

This is this line:

DataContext="{Binding MainWindowViewModel, Source={StaticResource ViewModelLocator}}">

Here is the code:

App.xaml

<Application x:Class="ViewModelLocatorDemo.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:viewModelLocatorDemo="clr-namespace:ViewModelLocatorDemo">
    <Application.Resources>
        <viewModelLocatorDemo:ViewModelLocator x:Key="ViewModelLocator"/>
    </Application.Resources>
</Application>

App.xaml.cs

namespace ViewModelLocatorDemo
{
    using System.Windows;
    using ViewModelLocatorDemo.Views;

    public partial class App : Application
    {
        protected override void OnStartup(StartupEventArgs e)
        {
            base.OnStartup(e);

            MainWindow mainWindow = new MainWindow();
            mainWindow.Show();
        }
    }
}

ViewModelLocator.cs

namespace ViewModelLocatorDemo
{
    using ViewModels;

    public class ViewModelLocator
    {
        public MainWindowViewModel MainWindowViewModel
        {
            get { return new MainWindowViewModel(); }
        }
    }
}

MainWindow.xaml

<Window x:Class="ViewModelLocatorDemo.Views.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d"
        Title="MainWindow" Height="300" Width="300"
        DataContext="{Binding MainWindowViewModel, Source={StaticResource ViewModelLocator}}">
    <Grid>
        <Frame x:Name="MainFrame" Margin="50" BorderThickness="2" BorderBrush="Black" />
    </Grid>
</Window>

MainWindowViewModel.cs

namespace ViewModelLocatorDemo.ViewModels
{
    public class MainWindowViewModel
    {
        public string MainText { get; set; }

        public MainWindowViewModel()
        {
            MainText = "The first page";
        }
    }
}

In this answer I found:

Make sure that the resources are defined before the usage (in Xaml parsing order). The easiest way is to place it into App.xaml

So I have it in App.xaml. If somebody would me explain what's going on here? Why am I getting this error?

1

There are 1 best solutions below

0
On BEST ANSWER

You are running into this bug WPF - App.xaml file does not get parsed if my app does not set a StartupUri?

From that page:

There's a VS code generation bug where the code necessary to connect to the rest of the program sometimes is not inserted when contains only one entry and does not have a StartupUri attribute.

From that page, there are 3 solutions (summarizing here for completeness):

  • Add x:Name="App"
  • Add more resources in App.xaml like <viewModelLocatorDemo:ViewModelLocator x:Key="ViewModelLocator"/> and <viewModelLocatorDemo:ViewModelLocator x:Key="ViewModelLocator2"/>
  • Rather than overriding OnStartup, try using an event instead, Startup="Application_Startup"

This was definitely not obvious, and was difficult to troubleshoot and even find an answer for in my own search. Hopefully this answer will help others find the other answer.