13

Very simple problem but I'm making no progress so I thought I should ask...

I'm writing a small WPF prototype where I placed the boot up logics where I believe it belongs: In (the overridden) App.OnStartup method.

The problem is the method never gets called and I have no idea why!

I browsed around some and found someone saying the <Application> tag in App.xaml must specify the implementing class (App) in the "x:Class" attribute. I changed it from x:Class="Application" to x:Class="App" but it made no difference.

What am I missing here?

EDIT: Here's the code...

XAML:

<Application
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="App"
    ShutdownMode="OnMainWindowClose"
    StartupUri="MainWindow.xaml">
    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="Recources\Brushes\Brushes.xaml"/>
                <ResourceDictionary Source="Recources\Templates\Templates.xaml"/>
                <ResourceDictionary Source="Recources\Styles\GVSStyles.xaml"/>
                <ResourceDictionary Source="Recources\Styles\TimePicker.xaml"/>
                <ResourceDictionary Source="Recources\Icons\GVSIcons.xaml"/>
                <ResourceDictionary Source="Recources\Icons\BottleIcon.xaml"/>
                <ResourceDictionary Source="Recources\Styles\BusyAnimationStyle.xaml"/>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>
</Application>

Code behind...

protected override void OnStartup(StartupEventArgs e)
{
    base.OnStartup(e);

    // lower default framerate from 60 to 20 to save CPU ...
    Timeline.DesiredFrameRateProperty.OverrideMetadata(
        typeof(Timeline),
        new FrameworkPropertyMetadata { DefaultValue = 20 });

    hookUpViews();
    connectToServer();
}
Jonas Rembratt
  • 1,550
  • 3
  • 17
  • 39
  • Don't post it in comments please. Edit the question. – H.B. Jun 22 '11 at 21:35
  • Yes, I realized comments would be unreadable. It's in the question now... – Jonas Rembratt Jun 22 '11 at 21:39
  • And you are sure the method is not called? Have you set a breakpoint? – H.B. Jun 22 '11 at 21:42
  • Yes, I did set a breakpoint and it never gets hit. – Jonas Rembratt Jun 22 '11 at 21:47
  • In what namespace is the App-class? Are there multiple classes inheriting from Application in your solution? – H.B. Jun 22 '11 at 21:51
  • What struck me as really strange is that if I remove the StartupUri attribute the main window doesn't show. So, apparently the App class' initializaion code is called but OnStartup() doesn't seem to be included in it. Also, while I consider it a foul hack, I did try adding an event handler to the Startup event but got this compiler error: "'App' does not contain a definition for 'Application_Startup' and no extension method 'Application_Startup' accepting a first argument of type 'App' could be found... (clipped)" My guess is I've missed something very basic somewhere but I'm clueless to what – Jonas Rembratt Jun 22 '11 at 21:52
  • Edited my answer, your `x:Class` attribute lacks its namespace. (Unless you actually removed the default assembly namespace it gets upon template project creation) – H.B. Jun 22 '11 at 21:55

4 Answers4

27

Edit: Your XAML seems to not be associated with the code behind, the x:Class needs to include the namespace of your App class. e.g. MyWpfApplication.App.


Unless you post some code you just get wild guessing, here's mine: You didn't properly override the method but hide it with a method of the same name and signature.

This is what a working override should look like:

protected override void OnStartup(StartupEventArgs e)
{
    base.OnStartup(e);
    MessageBox.Show("!");
}

As suggested you can use the Startup event instead, but you don't have to, further the StartupUri will be executed in addition to the code in the override.

H.B.
  • 166,899
  • 29
  • 327
  • 400
  • Thanks H.B! Including the namespace did the trick. I have to say I'm a bit miffed that (a) the compiler didn't complain about not finding the referenced class and that (b) VS2010 didn't set the App class to be automatically referenced. This means overriding App methods will never work out of the box so to say. Anyway, thanks alot! – Jonas Rembratt Jun 22 '11 at 21:58
  • You're welcome glad it worked out; i have to say that i am a bit ashamed of my earlier cockiness, this problem could indeed have been solved without the code. Actually the `x:Class` should be correct out of the box, at least it has been for me. – H.B. Jun 22 '11 at 22:00
  • Don't be. I'm an experienced developer but WPF is very new to me so I appreciate you're taking the time. It's the second issue you've managed to help me out on. Really appreciate it mate! I hope I can do the same for you sometime! :O) – Jonas Rembratt Jun 22 '11 at 22:03
  • thanks for this. it can easily result from a rename of your application - that's how it happened to me (and this answer was helpful in figuring it out) - seems visual studio doesn't update the app xaml - that's probably the primary source of it. – Dave Rael Sep 18 '13 at 12:00
  • I love you. This was my problem. Now what to do with all this hair I pulled out. – cplotts Oct 31 '17 at 14:01
2

In my case I renamed the project and the namespace. Then all methods in the code behind didn't fire any more.

The x:Class still showed the old namespace. The App class was just referring another namespace what was out of use, and nothing complained about that.

So, you make short, you have to rename the x:Class, just the way you would do for 'regular' code files.

Patrick Hofman
  • 153,850
  • 22
  • 249
  • 325
2

You need the connect the EventHandler :

<Application x:Class="Abc.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             Startup="Application_Startup">
Philippe Lavoie
  • 2,583
  • 5
  • 25
  • 39
1

As an alternative to @Philippe's answer, you can also wire up in the code-behind:

public App()
{
  this.Startup += new StartupEventHandler(App_Startup);
}

void App_Startup(object sender, StartupEventArgs e)
{
   //do stuff here...
}
Brian Driscoll
  • 19,373
  • 3
  • 46
  • 65