Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Error: No matching constructor found on type

Tags:

c#

.net

wpf

xaml

I have a WPF application where I am using multiple forms. There is one main form which gets opened when we start the application which is know as MainWindow.xaml. This form then have multiple forms which gets opened depending on the user option. There is a form StartClassWindow.xaml. Currently I am working on this form so I want it to start directly instead of MainWindow.xaml. So to do this I changed the app.xaml startupuri:

<Application x:Class="Class.App"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         DispatcherUnhandledException="Application_DispatcherUnhandledException"
         StartupUri="StartClassWindow.xaml">
<Application.Resources>

</Application.Resources>
</Application>

But then it started giving error like below:

No matching constructor found on type 'Class.StartClassWindow'. You can use the Arguments or FactoryMethod directives to construct this type.' Line number '3' and line position '9'.

Here is the StartClassWindow.xaml.cs:

namespace Class
{
    public partial class StartClassWindow : System.Windows.Window
    {

       public StartClassWindow(string classData)
       {
          InitializeComponent();
          className = classData;
          function();
       }
       //rest of the code.
    }
}
like image 333
S Andrew Avatar asked Dec 26 '16 07:12

S Andrew


2 Answers

You need to add a parameter-less constructor to your StartClassWindow like this:

public StartClassWindow(string classData)
{
    InitializeComponent();
    className = classData;
    function();
}

public StartClassWindow()
{

}

Or if you don't want to have another constructor you can override the OnStartup method in the App.xaml.cs but you should remove the StartupUri="StartClassWindow.xaml" in your App.xaml first. Like below:

protected override void OnStartup(StartupEventArgs e)
{
    StartClassWindow st = new StartClassWindow("");
    st.Show();
}
like image 62
Salah Akbari Avatar answered Nov 06 '22 22:11

Salah Akbari


"Normally", your constructor must be parameterless:

public Login()

But, since you are using dependency injection, like this:

public Login(IUserService userService)

The constructor isn't parameterless, and the framework cannot instantiate the page if it's not told how to.

For this there are a couple of options:

Remove service from constructor

Just like this, but you'll need to access the userservice differently:

public Login()

pre .net 4.8, 4.7, using Unity (or Prism)

You can use a dependency injection framework like Unity to register the components. It is described here:

https://www.wpftutorial.net/ReferenceArchitecture.html

public class App : Application
{
    protected override void OnStartup(StartupEventArgs e)
    {
        IUnityContainer container = new UnityContainer();
        container.RegisterType<IUserService, UserService>();
       
        MainWindow mainWindow = container.Resolve<MainWindow>();
        mainWindow.Show();
    }
}

Manual using Navigation Service

Manually navigate, and do your own construction:

NavigationService.Navigate(new LoginPage(new UserService);

As described here: https://learn.microsoft.com/en-us/dotnet/desktop/wpf/app-development/navigation-overview?view=netframeworkdesktop-4.8


.net 5 WPF, using built in DI

If you are using .net 5, here is a tutorial. Make sure to register both the window and the service:

https://executecommands.com/dependency-injection-in-wpf-net-core-csharp/

Here's an example:

private void ConfigureServices(ServiceCollection services)
{
    services.AddScoped<IUserService,UserService>();
    services.AddSingleton<MainWindow>();
}

private void OnStartup(object sender, StartupEventArgs e)
{
    var mainWindow = serviceProvider.GetService<MainWindow>();
    mainWindow.Show();
}
like image 34
Stefan Avatar answered Nov 07 '22 00:11

Stefan