19

Why does Application.Current come out to null in a WinForms application? How and when is it supposed to be set?

I am doing:

 static class Program {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main() {
            Application.Run(new MainForm());
        }
    }
Denis
  • 11,796
  • 16
  • 88
  • 150
  • 4
    There is no `System.Windows.Forms.Application.Current` property. Are you mixing with WPF? – Ivan Stoev Mar 09 '16 at 21:25
  • This is the background for this question and I am trying to implement the solution here: http://stackoverflow.com/questions/35901454/how-to-raise-onpropertychanged-on-a-gui-thread-when-an-object-property-is-modifi – Denis Mar 09 '16 at 21:26
  • 2
    The only answer in the linked question I see starts with *for **WPF***. – Ivan Stoev Mar 09 '16 at 21:30
  • Does this answer your question? [Application.Current in ElementHost is null](https://stackoverflow.com/questions/12198244/application-current-in-elementhost-is-null) – StayOnTarget Feb 11 '20 at 14:02

3 Answers3

36

Application.Current is Specific for WPF Application. Therefore when you are using WPF controls in WinForms Application you need to initialize instance of WPF Application. Do this in your WinForms Application.

if ( null == System.Windows.Application.Current )
{
   new System.Windows.Application();
} 
jdaval
  • 610
  • 5
  • 10
  • 47
    Been a while since I've seen a Yoda Condition in C#. – Pierre-Luc Pineault Mar 09 '16 at 21:33
  • 2
    This looks like it shouldn't work, but it does! Looking at the reference source [link](https://referencesource.microsoft.com/#PresentationFramework/src/Framework/System/Windows/Application.cs,695cdb0677ca5996) there is a static field _appInstance which is set upon the first time the constructor is called. – Alan Singfield Jan 08 '21 at 17:08
1

Well IMHO opinion the other SO answer is not really the way to go for windows forms, although maybe not incorrect.

Normally you would use ISynchronizeInvoke for such a feature in WinForms. Every container control implements this interface.

You'll need to BeginInvoke() method to marshall the call back to the proper thread.

Based on your previous question the code would become:

public class SomeObject : INotifyPropertyChanged
{
    private readonly ISynchronizeInvoke invoker;
    public SomeObject(ISynchronizeInvoke invoker)
    {
        this.invoker = invoker;
    }

    public decimal AlertLevel
    {
        get { return alertLevel; }
        set
        {
            if (alertLevel == value) return;
            alertLevel = value;
            OnPropertyChanged("AlertLevel");
        }
    }

    private void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            this.invoker.BeginInvoke((Action)(() =>
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName))), null);

        }
    }
}

Where you pass the owning Form class to the constructor of SomeObject. The PropertyChanged will now raised on the UI thread of the owning form class.

Ric .Net
  • 5,540
  • 1
  • 20
  • 39
0

Based on this other SO question, Application.Current is a WPF feature and not a WinForm feature: Application.Current in ElementHost is null

There is an MSDN post that shows how to leverage the feature in Winform by adding some references to your code:

you can add a reference to PresentationFramework first:

1.In Solution Explorer, right-click the project node and click Add Reference.

2.In the Add Reference dialog box, select the .NET tab.

3.Select the PresentationFramework, and then click OK.

4.Add "using System.Windows.Shell;" and "using System.Windows;" to your code.

StayOnTarget
  • 11,743
  • 10
  • 52
  • 81
Doug Dawson
  • 1,254
  • 2
  • 21
  • 37