0

I need to customise the Main() method in my WPF application, so I have turned off the auto-generation of the main, by changing the Build Action of my App.xaml to 'Page' (instead of 'ApplicationDefinition'). However, I also need to use a ResourceDictionary, and if the App.xaml isn't marked as 'ApplicationDefinition', none of the resources get imported (I tried this, see here).

I need a custom Main() method because the application is required to be a singleton, to the main simply reads:

[STAThread]
public static void Main()
{
    MainApplication app = MainApplication.Instance;
    app.Run();
}

No how do I automatically import all resources and define my own main at the same time?

One solution is to import them programatically, e.g. like this:

ResourceDictionary dict = new ResourceDictionary();
dict.Source = new Uri("/MyProject;component/MyResourceDictionary.xaml", UriKind.Relative);
Application.Current.Resources.MergedDictionaries.Add(dict);

This solution is not acceptable, though, as I want to be able to give my application to a designer who uses Blend and may know nothing about the background of the programme. So he would not be permitted to create new resource files, which is not ideal. Any better suggestions?

Community
  • 1
  • 1
Yellow
  • 3,955
  • 6
  • 45
  • 74
  • `I need to customise the Main() method in my WPF application` - What for? – Federico Berasategui Nov 18 '13 at 14:59
  • Cause I need it to be a singleton, and thus refer to the Instance of the object in the main, rather than create a `new` one. – Yellow Nov 18 '13 at 15:00
  • 2
    You should do that in `OnStartup()` in `app.xaml.cs` instead. Leave the `Main()` alone and the `ApplicationDefinition` too. – Federico Berasategui Nov 18 '13 at 15:02
  • Ok, could you maybe be a bit more specific on how to 'do that in `OnStartup()`? Cause now a `Main()` method is just being generated for me, with no chance of changing this into a singleton-like call. – Yellow Nov 18 '13 at 15:09
  • I have no idea because you have not shown the code you're currently using in `Main()`, but probably just move that to `OnStartup()`? – Federico Berasategui Nov 18 '13 at 15:10
  • Fair enough, I updated the question. It's super tiny, the only thing that is done is calling an Instance of the class, instead of calling `new MainWindow()`. – Yellow Nov 18 '13 at 15:17
  • What in the world is that code supposed to do? Where is `Instance` coming from? what are you trying to achieve? – Federico Berasategui Nov 18 '13 at 15:18
  • Well, obviously I am trying to keep my question concise so I can't elaborate on what the whole Instance does. Suffice it to say the Instance is of type `MainWindow`, and returns a single static instance of the class, and creates it if doesn't exist yet. Why my application has to be a singleton is beyond the scope of this question and this discussion, I believe. – Yellow Nov 18 '13 at 15:21
  • 1
    "So he would not be permitted to create new resource files" - this designer is going to have _SO MUCH FUN_. – Gusdor Nov 18 '13 at 15:21
  • @Yellow you have no idea what you're talking about. Leave the main method alone, and your application is not going to be "singleton" (whatever that means) by putting a static property anywhere. There are different means for that. if what you're trying to achieve is a `Single instance application`. – Federico Berasategui Nov 18 '13 at 15:23
  • @HighScore: A singleton is a very common design pattern, try google it, or see this question: http://stackoverflow.com/questions/3827612/how-to-make-my-wpf-mainwindow-a-singleton . But my experience with C# and VS is not high, hence this question. Could you please try some constructive criticism/comments instead of telling me how stupid I am? – Yellow Nov 18 '13 at 15:32

2 Answers2

1

I strongly recommend that you leave the Main() method to the default.

what you're trying to achieve here requires no custom code, and even if it did, the Main() method is NOT the right place to put that custom code.

You don't need to create a "singleton" property for the Application object in WPF, because WPF already does that.

You can access the "singleton" instance of the Application object in WPF via the System.Windows.Application.Current property:

So that if you put custom properties in the App class, like this:

public partial class App : Application
{
    public string MyString { get; set; }

    protected override void OnStartup(StartupEventArgs e)
    {
        base.OnStartup(e);
        MyString = "I'm a string in the App class";
    }
}

Then you can access that in XAML:

<TextBox Text="{Binding MyString, Source={x:Static Application.Current}}"/>

Or, if you need to access the instance of the MainWindow, then you can do:

<TextBox Text="{Binding Title, 
                        Source={x:Static Application.Current.MainWindow}}"/>

or

<TextBox Text="{Binding DataContext.MyString, 
                        Source={x:Static Application.Current.MainWindow}}"/>

for properties that are in the MainWindow's ViewModel.

Federico Berasategui
  • 43,562
  • 11
  • 100
  • 154
  • Thanks, this is very helpful indeed. Shame the singleton approach doesn't work. I know that one can bind to static variables (but thank you for the helpful examples), but `PropertyChanged` events work very oddly with such bindings. Nearly everyone therefore recommends using the singleton pattern. But I guess that in these examples there is still a way to work around that. – Yellow Nov 19 '13 at 10:42
0

If you had titled your question accurately, something like How to create a singleton WPF application?, then I'm sure that you would have received several replies by now. However, luckily I read the comments and saw your remark stating that requirement.

There are many tutorials online showing how to achieve your actual requirement. For example, you could take a look at the C# .NET Single Instance Application page on the Sanity Free Coding website which uses the Mutex class. If that one doesn't suit you, just search for others until you find one that does.

Sheridan
  • 68,826
  • 24
  • 143
  • 183
  • Sorry, I tried to give my question as accurate a title as I can, but it is hard to formulate a question if you do not know the answer. Please feel free to suggest a title you deem more accurate. – Yellow Nov 18 '13 at 15:27
  • If your overall requirement is 'to create a singleton WPF application?', then perhaps your title could be 'How to create a singleton WPF application?'. The general idea is to put what you're trying to achieve overall in your title and put exact details in the question. Either way, it's not a problem for us... it's potentially more of a problem for you. As a side note, was that link any use to you... is that the kind of thing that you were looking for, or did I misunderstand your requirements? – Sheridan Nov 18 '13 at 15:39
  • I do not actually think this is helpful. I know about Mutex/Single instance application/Singleton, but I fail to see what's wrong with using the Instance way (like so:http://stackoverflow.com/questions/3827612/how-to-make-my-wpf-mainwindow-a-singleton). I used this because it make it very easy to set Bindings to the main application, which was a suggestion somewhere else on this forum. My *actual* question is: why does the `ResourceDictionary` suddenly not work any more when your application defines it's own Main()? – Yellow Nov 18 '13 at 15:39
  • @Yellow there's nothing wrong in putting a singleton `property` anywhere. But that will `not` make your application `single-instance`. I'm not sure if that's what you're trying to achieve. And yes, WPF doesn't work properly if you mess with it's default startup mechanism. once again, leave the `Main()` alone – Federico Berasategui Nov 18 '13 at 15:54
  • I never said it did, my reasons for using the the Instance where purely to make the Bindings to the static property work easily, hence the need to slightly tweak the Main() method. And only much later, in the GUI design phase, I found out that this is problematic for reasons I don't understand. So *that* was my actual question, not the whole singleton stuff. – Yellow Nov 18 '13 at 16:01