I have a C# WPF application following the Model View ("MainWindowView") ViewModel ("MainWindowViewModel") pattern. Everything works fine. No error messages of any kind.
However, things fall apart when i try to implement a Splash Screen Window ("SplashScreenWindow") at the start of the application using the following code: https://riptutorial.com/wpf/example/25400/creating-splash-screen-window-with-progress-reporting
The code for the Splash Screen Window works completely fine: the Splash Screen Window appears and closes properly. However, I am unable to transition from the SplashScreenWindow to my MainWindowView, getting the following "Exception Thrown" message:
System.Windows.Markup.XamlParseException: ''The invocation of the constructor on type 'Notes.ViewModels.MainWindowViewModel' that matches the specified binding constraints threw an exception.' Line number '20' and line position '10'.'
Inner Exception InvalidCastException: Unable to cast object of type 'Notes.Views.SplashScreenWindow' to type 'Notes.Views.MainWindowView'.
Note that Line 20 and Line Position 10 in MainWindowViewModel is the viewmodels:MainWindowViewModel line in the following code:
<Window.DataContext>
<viewmodels:MainWindowViewModel />
</Window.DataContext>
Note again that without the splash screen window, the application based on MainWindowView and MainWindowViewModel works completely fine. I am stuck because when i search the net for items related to the components of the error message, i don't seem to get to anything that is remotely related to closing a window and opening a MainWindow. Any advice on what might be causing this error would be greatly appreciated. Thanks!!
Here are the various code pieces:
App.xaml
<Application x:Class="Notes.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
xmlns:local="clr-namespace:Notes" >
</Application>
App.xaml.cs
(source: https://riptutorial.com/wpf/example/25400/creating-splash-screen-window-with-progress-reporting)
using Notes.Views;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
namespace Notes
{
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
//initialize the splash screen and set it as the application main window
var splashScreen = new SplashScreenWindow();
this.MainWindow = splashScreen;
splashScreen.Show();
//in order to ensure the UI stays responsive, we need to
//do the work on a different thread
Task.Factory.StartNew(() =>
{
//we need to do the work in batches so that we can report progress
for (int i = 1; i <= 100; i++)
{
//simulate a part of work being done
System.Threading.Thread.Sleep(30);
//because we're not on the UI thread, we need to use the Dispatcher
//associated with the splash screen to update the progress bar
splashScreen.Dispatcher.Invoke(() => splashScreen.Progress = i);
}
//once we're done we need to use the Dispatcher
//to create and show the main window
this.Dispatcher.Invoke(() =>
{
//initialize the main window, set it as the application main window
//and close the splash screen
var mainWindowView = new MainWindowView();
this.MainWindow = mainWindowView;
mainWindowView.Show();
splashScreen.Close();
});
});
}
}
}
SplashScreenWindow.xaml:
<Window x:Class="Notes.Views.SplashScreenWindow"
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"
xmlns:viewmodels="clr-namespace:Notes.ViewModels"
xmlns:local="clr-namespace:Notes.Views"
mc:Ignorable="d"
Title="SplashScreenWindow" Height="300" Width="500" WindowStartupLocation="CenterScreen" ResizeMode="NoResize" WindowStyle="None" Background="DarkBlue">
<Grid>
<ProgressBar x:Name="progressBar" />
<TextBlock HorizontalAlignment="Center"
VerticalAlignment="Center">Loading...</TextBlock>
</Grid>
</Window>
SplashScreenWindow.xaml.cs:
using System.Windows;
namespace Notes.Views
{
/// <summary>
/// Interaction logic for SplashScreenWindow.xaml
/// </summary>
public partial class SplashScreenWindow : Window
{
public SplashScreenWindow()
{
InitializeComponent();
}
public double Progress
{
get { return progressBar.Value; }
set { progressBar.Value = value; }
}
}
}
MainWindowView.xaml.cs
using Notes.Models;
using Notes.ViewModels;
using System;
using System.Data;
using System.Diagnostics;
using System.IO;
using System.Windows;
using System.Windows.Documents;
namespace Notes.Views
{
/// <summary>
/// Interaction logic for MainWindowView.xaml
/// </summary>
public partial class MainWindowView : Window
{
public MainWindowView()
{
InitializeComponent();
}
}
}
MainWindowView.xaml
<Window x:Class="Notes.Views.MainWindowView"
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"
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
xmlns:viewmodels="clr-namespace:Notes.ViewModels"
xmlns:models="clr-namespace:Notes.Models"
xmlns:local="clr-namespace:Notes.Views"
xmlns:usercontrols="clr-namespace:Notes.UserControls"
xmlns:converters="clr-namespace:Notes.Converters"
mc:Ignorable="d"
Background="Black"
d:DesignWidth="2736" d:DesignHeight="1500"
WindowStartupLocation="CenterScreen"
MinWidth="1550" MinHeight="1221">
<Window.DataContext>
<viewmodels:MainWindowViewModel />
</Window.DataContext>
</Window>
View Model Constructor
public MainWindowViewModel()
{
// Assign application settings to application variables
GetSettings();
// Establish connection to database
DatabaseMethods.EstablishConnection(DatabasesFolderPath, DatabaseMainFileName);
// Open connection to database
DatabaseMethods.OpenConnection();
// Initialize SQL query statement
SQLMethods.InitializeSQLComponents();
InitializeVariables();
}
Window
there? Btw. the tutorial you are following is terrible. It looks outdated too. – BionicCodeApplication.Current.MainWindow
somewhere in your view model? – BionicCodereadonly MainWindowView MainWindowViewInstance = (MainWindowView)Application.Current.MainWindow;
I use this to be able to refer to the instance of the MainWindowView. – scorpiotomse