C
C#15h ago
wildREA

Manually Showing MainWindow.xaml In App.xaml.cs (Dependency Injection)

Hey! My code is supposed to manually show MainWindow.xaml, but it doesn't if I remove StartupUri="MainWindow.xaml" and I get the error that is listed with details below with it. Without it, I get no error, so it must be my logic. The way I wrote it is because of dependency injection for AppLanguageServices. App.xaml
<Application x:Class="computerComponentsTracker.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Application x:Class="computerComponentsTracker.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
App.xaml.cs
private static IServiceProvider? ServiceProvider;

protected override void OnStartup(StartupEventArgs e)
{
var serviceCollection = new ServiceCollection();

// Register services
serviceCollection.AddSingleton<IAppLanguageServices, AppLanguageServices>();
serviceCollection.AddTransient<ComponentUsage>();
serviceCollection.AddTransient<MainWindow>();
serviceCollection.AddTransient<Settings>();

// Build service provider
ServiceProvider = serviceCollection.BuildServiceProvider();

// Manually create and show MainWindow
var mainWindow = ServiceProvider.GetRequiredService<MainWindow>();
mainWindow?.Show();

base.OnStartup(e);
}
private static IServiceProvider? ServiceProvider;

protected override void OnStartup(StartupEventArgs e)
{
var serviceCollection = new ServiceCollection();

// Register services
serviceCollection.AddSingleton<IAppLanguageServices, AppLanguageServices>();
serviceCollection.AddTransient<ComponentUsage>();
serviceCollection.AddTransient<MainWindow>();
serviceCollection.AddTransient<Settings>();

// Build service provider
ServiceProvider = serviceCollection.BuildServiceProvider();

// Manually create and show MainWindow
var mainWindow = ServiceProvider.GetRequiredService<MainWindow>();
mainWindow?.Show();

base.OnStartup(e);
}
46 Replies
FusedQyou
FusedQyou15h ago
This is WPF?
wildREA
wildREAOP15h ago
System.Windows.Markup.XamlParseException: ''No matching constructor found on type 'computerComponentsTracker.MainWindow'. You can use the Arguments or FactoryMethod directives to construct this type.' Line number '6' and line position '9'.'
System.Windows.Markup.XamlParseException: ''No matching constructor found on type 'computerComponentsTracker.MainWindow'. You can use the Arguments or FactoryMethod directives to construct this type.' Line number '6' and line position '9'.'
internal static void RewrapException(Exception e, IXamlLineInfo lineInfo, Uri baseUri)
{
throw WrapException(e, lineInfo, baseUri);
}
internal static void RewrapException(Exception e, IXamlLineInfo lineInfo, Uri baseUri)
{
throw WrapException(e, lineInfo, baseUri);
}
Yes, it is WPF.
FusedQyou
FusedQyou15h ago
You have to set MainWindow in the app
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);

MainWindow = new MainWindow();
MainWindow.Show();
}
}
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);

MainWindow = new MainWindow();
MainWindow.Show();
}
}
Just making and showing the window doesn't work, you have to explicitly replace the MainWindow property for it to work Otherwise it assumes it has to use StartupUri which would be required
wildREA
wildREAOP15h ago
What about the ServiceProvider in my code line?
var mainWindow = ServiceProvider.GetRequiredService<MainWindow>();
mainWindow?.Show();
var mainWindow = ServiceProvider.GetRequiredService<MainWindow>();
mainWindow?.Show();
FusedQyou
FusedQyou15h ago
Doesn't matter, you don't set MainWindow MainWindow is a property in Application, mainWindow is your local variable So set MainWindow, not mainWindow You can do whatever you want, you just have to set MainWindow inside the startup which you're not doing. You can use DI like you do now. @wildREA works?
wildREA
wildREAOP14h ago
protected override void OnStartup(StartupEventArgs e)
{
var serviceCollection = new ServiceCollection();

// Register services
serviceCollection.AddSingleton<IAppLanguageServices, AppLanguageServices>();
serviceCollection.AddTransient<ComponentUsage>();
serviceCollection.AddTransient<MainWindow>();
serviceCollection.AddTransient<Settings>();

// Build service provider
ServiceProvider = serviceCollection.BuildServiceProvider();

// Manually create and show MainWindow
MainWindow = new MainWindow(ServiceProvider);
MainWindow.Show();

base.OnStartup(e);
}
protected override void OnStartup(StartupEventArgs e)
{
var serviceCollection = new ServiceCollection();

// Register services
serviceCollection.AddSingleton<IAppLanguageServices, AppLanguageServices>();
serviceCollection.AddTransient<ComponentUsage>();
serviceCollection.AddTransient<MainWindow>();
serviceCollection.AddTransient<Settings>();

// Build service provider
ServiceProvider = serviceCollection.BuildServiceProvider();

// Manually create and show MainWindow
MainWindow = new MainWindow(ServiceProvider);
MainWindow.Show();

base.OnStartup(e);
}
This is my current line of code. It does not work and I need ServiceProvider as a required parameter, otherwise I assume I'd get an error due to a missing argument.
FusedQyou
FusedQyou14h ago
private static IServiceProvider? ServiceProvider;

protected override void OnStartup(StartupEventArgs e)
{
var serviceCollection = new ServiceCollection();

// Register services
serviceCollection.AddSingleton<IAppLanguageServices, AppLanguageServices>();
serviceCollection.AddTransient<ComponentUsage>();
serviceCollection.AddTransient<MainWindow>();
serviceCollection.AddTransient<Settings>();

// Build service provider
ServiceProvider = serviceCollection.BuildServiceProvider();

// Manually create and show MainWindow
- var mainWindow = ServiceProvider.GetRequiredService<MainWindow>();
- mainWindow?.Show();
+ MainWindow = ServiceProvider.GetRequiredService<MainWindow>();
+ MainWindow?.Show();

base.OnStartup(e);
}
private static IServiceProvider? ServiceProvider;

protected override void OnStartup(StartupEventArgs e)
{
var serviceCollection = new ServiceCollection();

// Register services
serviceCollection.AddSingleton<IAppLanguageServices, AppLanguageServices>();
serviceCollection.AddTransient<ComponentUsage>();
serviceCollection.AddTransient<MainWindow>();
serviceCollection.AddTransient<Settings>();

// Build service provider
ServiceProvider = serviceCollection.BuildServiceProvider();

// Manually create and show MainWindow
- var mainWindow = ServiceProvider.GetRequiredService<MainWindow>();
- mainWindow?.Show();
+ MainWindow = ServiceProvider.GetRequiredService<MainWindow>();
+ MainWindow?.Show();

base.OnStartup(e);
}
This is all you need to do
wildREA
wildREAOP14h ago
I already tried that, but I can try again and see if I maybe have had done something wrong.
FusedQyou
FusedQyou14h ago
Worked for me 🤷‍♂️ In a minimal application this is all that's required for manual creation of the window @wildREA ?
wildREA
wildREAOP14h ago
Sorry for forgetting to respond. I have a senior colleague try help me out, but we couldn't initially figure it out. He found me a YouTube video I should try and watch and see if it helps. The thing you gave me did not work.
FusedQyou
FusedQyou14h ago
What does it say though Like, what's the error now
wildREA
wildREAOP14h ago
The OnStartup method has 0 references, so it does not ever run at all.
FusedQyou
FusedQyou14h ago
OnStartup is an overridden method which is called on app load. You can verify it by placing a breakpoint inside of it You don't have to call it WPF does it for you
wildREA
wildREAOP14h ago
The problem is that it never runs since it, as I said, has 0 references, so something is mysteriously incorrect. I have interfaces setup for IServiceProvider, but since OnStartup doesn't run even with correct syntax for registering services, it cannot run since, well, it has no references as I mention again.
FusedQyou
FusedQyou14h ago
How did you verify this? Did you place a breakpoint in it?
wildREA
wildREAOP14h ago
I did it by using a breakpoint and generally reading that there aren't any references.
No description
FusedQyou
FusedQyou14h ago
0 references at the top is something you should not be reading here This is an internal method you override and internal code calls it So this is not an issue with main window at this point, your method is not called
wildREA
wildREAOP14h ago
Oh right, but it still never runs.
FusedQyou
FusedQyou14h ago
So what does this setting say in your csproj properties?
No description
FusedQyou
FusedQyou14h ago
Also, are you starting the correct project? Make sure you have the project as the startup project
No description
FusedQyou
FusedQyou14h ago
Something is either blocking this code from running because something else is run, or you didn't compile the changes at all
wildREA
wildREAOP14h ago
No description
FusedQyou
FusedQyou13h ago
If that doesn't solve it I suggest you delete the bin and obj folder from your project, recompile, and check again It would also help if you shared all the code and the exception more properly Also, this exception generally suggests you still use parameters somewhere where you should not use them I have only seen 0.01% of the code so I can only assume somewhere you have an Application/Window/Control constructor that takes parameters So you should verify that's not the case Would be nice if we could continue the conversation in a steady manner rather than having huge pauses by the way Unless your issue is resolved
wildREA
wildREAOP13h ago
Is it okay with you if I enter a voice channel with you tomorrow after college? By the way, I had break for 30 minutes, so that's why there was such a huge pause.
FusedQyou
FusedQyou13h ago
I see I don't want to join a voice channel because generally it won't improve the conversation I just want to have more context, like the current error and the code that is actually used here Also considering I asked you to check various things, such as the constructors, and I have no clue what the answer to those would be
wildREA
wildREAOP13h ago
Here is my repo.
MODiX
MODiX13h ago
FusedQyou
I have only seen 0.01% of the code so I can only assume somewhere you have an Application/Window/Control constructor that takes parameters
React with ❌ to remove this embed.
FusedQyou
FusedQyou13h ago
-public MainWindow(IServiceProvider serviceProvider)
+public MainWindow()
-public MainWindow(IServiceProvider serviceProvider)
+public MainWindow()
See how that changes things You'll have to add an explicit Initialize method in here and keep an empty constructor Generally you make factories because of this reason. Also something mentioned in the documentation @wildREA
wildREA
wildREAOP13h ago
public static ComponentUsage componentUsage;
public Settings settings;
private IServiceProvider _serviceProvider;

// Empty constructor
public MainWindow()
{
InitializeComponent();
}

// Explicit initialization
public void Initialize(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
InitializePages(_serviceProvider);
InitializeComponentPage(); // Set default page
}
public static ComponentUsage componentUsage;
public Settings settings;
private IServiceProvider _serviceProvider;

// Empty constructor
public MainWindow()
{
InitializeComponent();
}

// Explicit initialization
public void Initialize(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
InitializePages(_serviceProvider);
InitializeComponentPage(); // Set default page
}
This is how it looks now, but it does not open the window.
FusedQyou
FusedQyou13h ago
Does anything happen at all? Any errors? I can't imagine it just doesn't do anything unless you literally don't tell it to do anything, such as not showing the window at all
wildREA
wildREAOP13h ago
I've manually coded it to show MainWindow, but it doesn't. It runs without errors, but no window nonetheless. I'm referring to your suggested changes.
FusedQyou
FusedQyou12h ago
Next thing to do would be to verify it still gets to MainWindow?.Show() and see that it is non-null and calling it Also put a breakpoint inside the MainWindow's constructor to see if it's called Actually, I'll just clone your repo and check myself
wildREA
wildREAOP12h ago
The breakpoint tells me that public MainWindow does not run and MainWindow?.Show(); is not null. Just fork it.
FusedQyou
FusedQyou12h ago
It doesn't even run for me Like, doesn't even call the startup object
wildREA
wildREAOP12h ago
Now we're in the same boat.
FusedQyou
FusedQyou12h ago
You say it gets to the Show method though
wildREA
wildREAOP12h ago
No, I have figured out that theOnStartup method does not run.
FusedQyou
FusedQyou12h ago
I don't understand this then How can it not be null if it doesn't run Anyway the issue is your App isn't wrapped in a namespace
FusedQyou
FusedQyou12h ago
You removed it by accident 7 days ago
No description
wildREA
wildREAOP12h ago
Well, there is some progression. At least I have different errors now, of which are missing assembly references for IAppLanguageServices. This is just embarassing. Just for your information, I have break until 12 (XX:00).
FusedQyou
FusedQyou12h ago
All good If you want I can add a pull request that fixes this I'm just confused why the conversation started off with a whole different issue that seemed to suggest it worked for you initially Or was this an old version by any chance? The error I had personally was something about settings not being registered by DI, which is a matter of specifying it in the service collection To be fair, WPF is dumb as hell for not properly erroring because it can't find the entry point. I would expect something to break here but instead it just ignores it
wildREA
wildREAOP11h ago
Sure, go ahead. It was probably an older version. I have registered my services, and they should work, but yes, WPF is a work of deterred art.
FusedQyou
FusedQyou9h ago
Sorry, I got quite busy so I'm not sure if I can contribute to the change. I hope the fix is clear so maybe you can do it
wildREA
wildREAOP9h ago
It's fine, I've already implemented the changes. I've defined IAppLanguageServices and added the namespace, of which caused the language service assembly references to be missing. The problem is, the issue still persists with not receiving any errors, while not having the MainWindow show. Listen, you can contribute further if you'd like, but I'm done for today at 15:30 (XX:30), so I'll check on this either later today if I have time or tomorrow.
FusedQyou
FusedQyou8h ago
I'm quite busy at work currently but I can take a look at it later

Did you find this page helpful?