Home > behavior, Windows Presentation Foundation, Action > You see, you don’t always need code behind.

You see, you don’t always need code behind.

By now you should be aware that I’m a big fan of attached behaviors. In this post, I’m going to demonstrate a simple technique to add resize and close functionality to window buttons when you want to custom draw your window chrome without having to add code behind the window. This is going to be a quick post, because it’s just so darned easy.

Note: Originally I was using Application.Current.MainWindow to retrieve the window as I only ever apply this trick to the application main window. Mike Strobel suggested using Window.GetWindow instead to retrieve the logical window for the button, just in case it was in a separate window. I’ve adjusted the code sample here to demonstrate this as it makes this more reusable. Thanks Mike.

namespace AttachedTitleButtonsSample
{
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Interactivity;

    /// <summary>
    /// Attach this behaviour to a button to enable a button to change the window state without
    /// having to write any code behind the view.
    /// </summary>
    public partial class TitleButtonBehavior : Behavior<Button>
    {
        /// <summary>
        /// The tile button action to apply.
        /// </summary>
        public enum TitleButtonAction
        {
            /// <summary>
            /// Close the application
            /// </summary>
            Close,
            /// <summary>
            /// Maximize the application
            /// </summary>
            Maximize,
            /// <summary>
            /// Minimize the application
            /// </summary>
            Minimize,
            /// <summary>
            /// Reset the application to normal
            /// </summary>
            Normal
        }

        /// <summary>
        /// Gets or sets the button behavior.
        /// </summary>
        public TitleButtonAction ButtonBehavior { get; set; }

        /// <summary>
        /// Add the click handler when this is attached.
        /// </summary>
        protected override void OnAttached()
        {
            this.AssociatedObject.Click += AssociatedObject_Click;
            base.OnAttached();
        }

        /// <summary>
        /// Remove the click handler when this is detached.
        /// </summary>
        protected override void OnDetaching()
        {
            this.AssociatedObject.Click -= AssociatedObject_Click;
            base.OnDetaching();
        }

        /// <summary>
        /// Change the window state when the button is clicked.
        /// </summary>
        void AssociatedObject_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            Window window = Window.GetWindow(AssociatedObject);
            switch (ButtonBehavior)
            {
                case TitleButtonAction.Close:
                    window.Close();
                    break;
                case TitleButtonAction.Maximize:
                    window.WindowState = WindowState.Maximized;
                    break;
                case TitleButtonAction.Minimize:
                    window.WindowState = WindowState.Minimized;
                    break;
                case TitleButtonAction.Normal:
                    window.WindowState = WindowState.Normal;
                    break;
            }
        }
    }
}

Basically, all you need to do is create an attached behavior that hooks up to the Click event of the button and sets the size based on the appropriate value from the enumeration.

Sample application
I’ve attached a sample application that demonstrates this technique in action. As always, when you download the sample, you’ll need to rename it from a doc to a zip file.

AttachedTitleButtonsSampleZip

About these ads
  1. June 7, 2011 at 9:01 pm

    How about resolving the window using Window.GetWindow(this.AssociatedObject) so it works on the ancestor window instead of only with the application’s main window? :)

    • peteohanlon
      June 7, 2011 at 9:08 pm

      Blimey Mike. That was quick. I’ve only just posted this.

      Anyway, you could do that – I’ve never needed to do this on anything other than the application’s main window.

    • peteohanlon
      June 10, 2011 at 11:59 am

      I’ve decided to update the sample to show your most excellent reply.

  2. Ed
    June 9, 2011 at 5:06 pm

    On line 55 your adding the click handler again

    this.AssociatedObject.Click += AssociatedObject_Click;

    instead of removing it

    this.AssociatedObject.Click -= AssociatedObject_Click;

    • peteohanlon
      June 9, 2011 at 5:14 pm

      Thanks for spotting that. I can’t believe I missed it. Thanks.

  3. Al
    May 2, 2012 at 5:19 pm

    This information is great but I need to take the log4net viewing a step further. Instead of sending the raw messages to a textbox, I need to implement a mechanism in WPF of buffering these messages and displaying them in another object show the most recent message at the top of the list. Then I would like to be able to “freeze” the display so that the user can scroll through the messages, and then “unfreeze” it so that any new messages that where bufferred can not be displayed. I’m not sure how to “capture” the messages into a collection that in this example are going directly to a textbox. Do you have any suggestions?

  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

The Canny Coder

Java 8 Functional Programming with Lambda Expressions

pihole.org

Adventures in theoretical computer science, with your host, chaiguy1337

Confessions of a coder

Confessions of a WPF lover

WordPress.com

WordPress.com is the best place for your personal blog or business site.

Follow

Get every new post delivered to your Inbox.

Join 38 other followers

%d bloggers like this: