WPF Tip: avoid App.Current.Shutdown

In your WPF application’s Exit command handler, be wary of calling App.Current.Shutdown unless you want to bypass the normal ‘Close’ process. It can result in your override of Window.OnClosing to NOT be called, and your closing-event handlers don’t get called either.

If you override the Onclosing method, don’t forget to call the base class OnClosing!

Oh – if your WindowSettings functionality is not working, check for this mistake.

Of course I’ve never done that myself. Oh no. Neeeever.

Discussion:

If you are going to shutdown your application in code other than within the WPF Window or Page class, you can accomplish this by posting an event to the main window which will in turn close itself. If you want code to execute at the close of your application – you can override OnClosing within your Window subclass to accomplish this.

#region OnClosing
/// <summary>
/// This is an override of the event-handler for the Closing event.
/// </summary>
protected override void OnClosingCancelEventArgs e )
{
    UserSettings.SaveWindowPositionIfChangedthis );
    base.OnClosinge );
}
#endregion

This way, you can execute that code within your unit-tests and it will not try to force your running program (which may be your test-runner in this case) to shutdown – because you simply have not defined a handler for that event.

If you do want to call App.Shutdown, then you need to consider the case where it is running within a unit-test and you don’t have an App present to shutdown. In this case App.Current will be null and it would throw an exception where you try to call App.Current.Shutdown. Instead, you could code it thusly:

public void ShutdownApplication()
{
    App.Current?.Shutdown();
}

Here, if App.Current is null it does not make the call to the Shutdown method (as would be the case if this is running within a test-runner instead of the normal application-program).

 

James W. Hurst

Data-binding To A Simple C# Class (WPF or Silverlight)

When composing a WPF view sometimes you need to ‘bind’ a property of one of your widgets to some kind of information source. WPF’s data binding capabilities provide a way to accomplish this very easily in XAML for a range of scenarios. Here’s a trivial example.

Let’s say you want a TextBox to get it’s text from an object of your own C# class. Let’s contrive a gnarly little sample class to serve as our data source that just holds a single property:

namespace HurstOnWpfDataBinding1
{
    public class Person
    {
        public string FirstName
        {
            get { return _firstName; }
            set { _firstName = value; }
        }
 
        private string _firstName = "Aline";
    }
}

Consider this to be your “view-model”; in your XAML you bind to it using this syntax:

<TextBox Text="{Binding Path=FirstName}" />

What you are saying with this, in effect, is to get it’s value from the FirstName property of the binding source. You can get values only from properties – not from instance variables.

You can leave out the “Path” part – leaving this..

<TextBox Text="{Binding FirstName}" />

 

Where do we specify the binding source? One way is to simply do that in code; in the constructor after InitializeComponent, or in your event handler for the Loaded event:

public MainWindow()
{
    InitializeComponent();

    // Set the binding source here.
    MyClass viewModel = new MyClass();
    this.DataContext = viewModel;
}

 

Now it should work – when your Window pops up on the screen your TextBox fetches it’s text content from the FirstName property of your MyClass. Juuuust peachy.

But.. if you leave it as it is here, your TextBox won’t continue to update it’s text whenever the FirstName property changes! Why? Because it has no way of knowing; it fetches the property value just once as it initializes itself and renders itself on-screen.

Let’s fix that. We can use DependencyProperties, but for now why don’t we just reach for the simplest way available.

Change your source class to implement the INotifyPropertyChanged interface. This makes it send a notification to your XAML-defined TextBox of any important changes whenever you set a new value for that property. Here’s that same source class, with two essential changes. Take careful note of the change in your FirstName property…

 

using System.ComponentModel; // for INotifyPropertyChanged

namespace DesignForge
{
    public class MyClass : INotifyPropertyChanged
    {
        // This next region of code, is step ONE (of two) of what you need
        // to support the INotifyPropertyChanged interface.
        // I usually just copy it from a previous piece of code – it just works,
        // or, put it within a base-class.
        #region INotifyPropertyChanged implementation

        public event PropertyChangedEventHandler PropertyChanged;

        protected void Notify(string propertyName)
        {
            if (this.PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
        #endregion INotifyPropertyChanged implementation

        // This is step TWO.
        // For each of your properties whose changes you want to track
        // (that is, to cause the data bindings to update),
        // add the call to Notify within the setter as I did below.
        // The string that you put as the parameter to Notify,
        // must to be exactly the same as the name of the property
        // (just copy-paste it and it'll rarely be a source of mistake).
        public string FirstName
        {
            get { return _firstName; }
            set
            {
                // Do nothing unless the new value is different..
                if (value != _firstName)
                {
                    // Set the value.
                    _firstName = value;
                    // This next line is the only change within this property.
                    // Notify anyone who cares about this.
                    Notify("FirstName");
                }
            }
        }

        private string _firstName = "Naira";
    }
}

 

Now run your app and you should be seeing your GUI fields updating themselves to track the changes in your source class. This is the simplest example of a one-way binding and handles probably the majority of cases of this nature. Subsequent posts will cover more scenarios. Please shoot back a note to me if you spot any mistakes, problems or additional insight.

James W. Hurst