SettingsFlyout Class For C#/XAML Windows 8 Apps

One of the interesting things about Windows 8 Modern UI app development is the amount of boilerplate code that the project wizard adds to your project. Why some of the classes are not part of the WinRT base class library is not clear and not hugely important. It is more puzzling to think of the things that are not provided such as a settings flyout wrapper. If you're new to all this, the settings flyout1 is that thing that appears to the right when you use the Settings charm2. Windows has its own implementation for the system level Settings but your app must implement this for its own settings.

I discovered the hard way that to get certified in the Windows Store you must support the settings contract so you can provide "about" information. Adding this isn't particularly difficult, but there is a lot of boilerplate that can be abstracted away. Not only that, but if you're using the WebView, you need to know when the settings come and go to ensure the WebView is properly hidden as it would otherwise draw all over your beautiful settings (I'll perhaps talk about XAML apps and the WebView another time, when I've calmed down a bit).

To simplify this I wrote SettingsFlyout, a simple wrapper that handles the boilerplate activity of showing a UserControl as your settings while providing some handy events to track any settings flyout being shown or hidden. You may notice that other than the dimensions of this flyout, it could easily be adapted to support any of your flyout needs. However, I'm not sure that there are many valid reasons for flyout usage in Modern UI apps other than the standard system implementations and settings. Therefore, I'll leave that up to you, I'd hate to lead you into bad habits.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;

namespace SomewhatAbstract
{
    /// <summary>
    /// Provides a wrapper for showing settings with events to track any settings flyout coming or going.
    /// </summary>
    public class SettingsFlyout
    {
        private const int FlyoutWidth = 346;
        private Popup popup;

        /// <summary>
        /// Shows the given control in the flyout.
        /// </summary>
        public void ShowFlyout(UserControl control)
        {
            this.popup = new Popup();
            this.popup.Opened += OnPopupOpened;
            this.popup.Closed += OnPopupClosed;
            Window.Current.Activated += OnWindowActivated;
            this.popup.IsLightDismissEnabled = true;
            this.popup.Width = FlyoutWidth;
            this.popup.Height = Window.Current.Bounds.Height;

            control.Width = FlyoutWidth;
            control.Height = Window.Current.Bounds.Height;

            this.popup.Child = control;
            this.popup.SetValue(Canvas.LeftProperty, Window.Current.Bounds.Width - FlyoutWidth);
            this.popup.SetValue(Canvas.TopProperty, 0);
            this.popup.IsOpen = true;
        }


        private void OnWindowActivated(object sender, Windows.UI.Core.WindowActivatedEventArgs e)
        {
            if (e.WindowActivationState == Windows.UI.Core.CoreWindowActivationState.Deactivated)
            {
                this.popup.IsOpen = false;
            }
        }

        private void OnPopupClosed(object sender, object e)
        {
            Window.Current.Activated -= OnWindowActivated;
            OnSettingsClosed(EventArgs.Empty);
        }

        private void OnPopupOpened(object sender, object e)
        {
            OnSettingsOpened(EventArgs.Empty);
        }

        /// <summary>
        /// Raised to indicate settings flyout has been opened.
        /// </summary>
        public static event EventHandler SettingsOpened;
        private static void OnSettingsOpened(EventArgs args)
        {
            var handler = SettingsFlyout.SettingsOpened;
            if (handler != null)
            {
                handler(null, args);
            }
        }

        /// <summary>
        /// Raised to indicate settings flyout has been closed.
        /// </summary>
        public static event EventHandler SettingsClosed;
        private static void OnSettingsClosed(EventArgs args)
        {
            var handler = SettingsFlyout.SettingsClosed;
            if (handler != null)
            {
                handler(null, args);
            }
        }
    }
}

Using the SettingsFlyout class is as simple as this:

// Add an About command
var about = new SettingsCommand("about", "About", (handler) =>
{
    var settings = new SettingsFlyout();
    settings.ShowFlyout(new MyAboutSettingsControl());
});

If you find this useful or you did something similar yourself, I would love to hear about it. Is there something you feel is missing that should be there either in WinRT or the project template? Have you created any useful utility classes like this that could be used in almost every app?

  1. A flyout is the new Windows 8 modern UI term for what we might've called a popup, dialog or tooltip in the past. It's anything that appears over your application and you use a Popup control to show them as you would in Silverlight or WPF. []
  2. The Settings charm is the cog-like button that appears when you swipe from the right or hover your mouse in the lower right (or press Windows+C). It looks a lot like an icon, except it's not. It's a charm. []

Mouse without Borders and a VPN

When I'm working from home, I like to make use of the keyboard and mouse I normally use for my home super computer with my work laptop. Rather than unplug them from one machine to plug into the other, I use Mouse Without Borders.

Mouse Without Borders is awesome. It seamlessly integrates between the machines (with some customization options), allowing me to use both computers at the same time from the same keyboard and mouse, including clipboard and file drag-and-drop. I won't go into details on Mouse Without Borders, suffice to say that it is really rather lovely1.

However, I was having issues when working from home when it would just stop working. Both machines would report everything was fine and it seemed configured properly, yet the mouse would stop at the edge of one screen and no longer move other to the other. It was perplexing and annoying and I had no idea what was going on.

Then it hit me: I was using the work VPN. Mouse Without Borders uses the network to communicate between machines, so I quickly checked the Mouse Without Borders settings on my work laptop. There I discovered that it had switched over to the VPN.

Settings dialog for changing network binding in Mouse without Borders
Changing network binding in Mouse without Borders

I don't know idea why Mouse Without Borders does this on detecting my VPN IP address, but a quick change in the handy drop down fixes everything. Unfortunately, I appear to have to do this every time I use my VPN, but at least I now know what the heck is going on. Hopefully this will be helpful should you encounter the same issue.

  1. Amusing aside, while typing this on my home desktop, the wife brought me a lovely cup of tea and knocked the mouse over to my work laptop, stalling my blogging for a moment. I guess Mouse Without Borders has its downsides. []

I Have An Announcement To Make

This is going to come as a shock to friends and family alike, so please, take a seat. I have to tell you that Chrissy and I are, as of Friday, the proud parents of a child. One imaginary, completely made-up, sexless, physically unmanifested and nameless child.

As with most fake children, the conception, gestation and birth occurred within moments of one another. And it is all my fault (typical that I get the blame, huh, gents?).

If you would be so kind as to remain seated, I will explain myself (I apologise if this gets a bit graphic as I'm going to be honest about the details which may include cussing, just be grateful I did not video the birth, I certainly am).

A Typical Friday Morning

It all happened on Friday morning when I took my car for a scheduled service. The service greeter guy (official title, I believe) greeted me by name, having remembered me from my last service six months ago when he had kindly arranged for important work to be done under warranty1. He proceeded to fill out paperwork and inspect the car.

The car had not done many miles since the last service, so he wanted to double check if the tyres needed rotating (tire, as he said it, because he is American and therefore speaks in different spellings). From a quick check of the tread, he decided that only the right-side tyres needed rotating "to keep my kids safe". And this is where I made my first mistake. I started thinking.

He thinks we have kids. Shit. Do we? I don't know. Of course we don't, how don't you know? Oh fuck. What do I do? Correct him. Correct him! Shit, too late. We've moved on. Now it will just be weird. Nevermind.

So, I did not correct him. In my defense, it did feel a bit asinine to point that out. After all, he was really just saying he wanted people in my car to be safe and that is a nice thing, so I let the small inaccuracy of "kids" slip by, leaving Service Greeter Guy to continue in his belief that I had kids. Instead, I had the bright idea to change the subject.

ME: "I'm probably going to get a new car soon."

SGG: "Well, how many kids have you got?"

What?! Clearly Service Greeter Guy did not know the rules of changing the subject.

“At first sign of crisis, the ignorant don’t panic because they don’t know what’s going on, and then later they panic precisely because they don’t know what’s going on.
”2

At this point my subconscious started to determine what my next move should be in this battle of wits. The sane part of me said I should come clean and tell him we did not have any kids, but that is too much like normal. I do not do normal very well.

Shit! He asked how many kids we have. Are we supposed to have kids? Is it wrong not to have any kids? Fuck. Fuck. FUCK! We have…er…shit. Don't hesitate. Now he looks puzzled, "Why doesn't he know how many kids he has?" Why are you not speaking?

ME: "It depends."

It depends?! Depends on what? How many I've kidnapped on a given day? What the fuck?

I had somehow determined that this hole was far from deep enough and started furiously digging. Service Greeter Guy looked confused and why would he not? I was confused and panicking.

SGG: "No, just you and your wife."

Fortunately for me, while I was panicking, Service Greeter Guy appeared to have been searching for a rational reason why the strange British man might say "It depends" to such a straightforward question. I can only assume he had decided that we ferry local kids around for some after school club or some equally normal activity where the number of kids in my car might vary. Of course, he was not going to get off so lightly. Tossing aside this opportunity to set everything straight, take the hit of embarrassment and move on, I kept digging.

ME: "One."

All of a sudden and there it was, our imaginary child, fresh from the womb of insanity, waiting to be saved by the tyre rotation that had conceived it.

Service Greeter Guy continued with his day, unaware that I had lied to him for no reason whatsoever other than the growing panic inside me, feeling like I might be judged for not having children. While he calmly tapped at keys and got me a ride to work, I calmly considered the impact of my new ward's inexistence.

One? We have one? FUCK! Now I have to have at least one kid for the rest of my days coming here to fix my car. Fuck. Will he remember? Yes, he'll remember! He remembered your fucking name when you drove in this morning from six months ago. Arse. Can I borrow a kid?

"Parenthood always comes as a shock. Postpartum blues? Postpartum panic is more like it. We set out to have a baby; what we get is a total takeover of our lives."3

If it were not for a chat with my wife later in the day, our happy news of  September 28th, 2012 may have been known only to me. However, it was her fake kid too, so I wanted to share with her the overwhelming burden of parenthood. Of course, she happily wanted me to share it with everyone, which is why I have written it down here for all to revel in my weirdity.

If you want to send birthday cards, gifts (no obligation, but it loves beer) or just a comment, have at it. Perhaps you even have ideas on what we can do with our new child. Name it? Give it a sibling? Kill it? Please share.

  1. I do know Service Greeter Guy's name, I'm just choosing to omit it. []
  2. Jarod Kintz, At even one penny, this book would be overpriced. In fact, free is too expensive, because you'd still waste time by reading it. []
  3. Polly Berrien Berends []

Differences of Opinion

This was originally a status post I made on my Facebook timeline, but I thought it was worth sharing outside of that walled garden. I've edited it to account for the change in context (this being my blog, not Facebook), but only a little.

I am very happy to have a lot of wonderful friends from both sides of the political fence; they challenge my thinking and I value that. I hope all my friends understand that while we may not always agree, I appreciate their friendship and their willingness to accept our differences as I do.

However, I also accept that at some point, my views may push some away, as it did yesterday when a perhaps ill-considered post on Facebook led someone to un-friend me. It is a shame when someone chooses to walk away (figuratively or otherwise), but it happens.

I disagree with many people. I may or may not believe in God though I do believe in what I was taught as a Christian. I get things wrong. I am quick to judge sometimes and act on impulse. I don't believe it is right to force spiritual and religious beliefs on others. I accept that others have different beliefs than mine. I don't know if there is a God or not, though I think not. However, I do know that if God exists, He made me this way for a reason. I believe He wouldn't appreciate the heinous things people do in His name. I believe everyone deserves the same rights for a reason, regardless of their race, creed, sexuality or personal beliefs. I believe I am allowed to question everything and accept nothing on face value for a reason. I believe no one but a woman has a right to control what she does with her own body for a reason.

It's okay to disagree with me. It's okay to think I'm wrong. It's just not okay to tell me to shut up or hide my views just because they make you uncomfortable. If you feel uncomfortable, look inside yourself to find out why, don't look at others. They don't control how you feel, you do.

Rain Barrel Revisited

Chrissy grinning over our rain barrel
Chrissy grinning over our rain barrel
Earlier this year, my wife, Chrissy and I attended a workshop on making a rain barrel. Since then, the rain barrel has sat in the corner of our garage awaiting someone1 to prepare a suitable home for it in our garden (more commonly referred to as a yard round these parts).

While my wife was eager for someone to get the rain barrel set up immediately, I was formulating a plan.

Then

When we were looking for a house, we had a list of things we wanted. One of the top three items on our list, alongside a fireplace and a finished basement, was a deck. The house we eventually bought, our house, not only had a fireplace and a basement that had enough potential to overlook its unfinished state, it also had a deck. Perfect.

Now

Looking back now, we were merely young and naive. We didn't have a clue what we really wanted, we just guessed a little. It turns out that while we love the fireplace that we don't use often enough and we're excited about finishing the basement sometime in the future, the deck was an impostor, a dictator that divided and overpowered our back garden. When we bought the house, a deck had sounded like a great idea but in reality, it turned out to be a bit rubbish. What we really wanted was a patio. My plan was to put our rain barrel on that patio.

Of course, that meant getting rid of the deck and building a patio. I'll leave the patio building to another post (I'm waiting for the grass to grow to take the last few "after" pictures) but I can tell you that it looks great and we are much happier about the way our back garden is looking (not to mention that the garden is quite pleased to have been liberated). And with the patio in place, someone2, with the fantastic assistance of our neighbour, was able to install the rain barrel.

Installation

The rain barrel is best positioned near a downspout (also known as a drainpipe in some parts) so that water from the roof can be collected. I earmarked a spot on the corner of our patio where the barrel fit perfectly. Next, my neighbour reveled in the opportunity to use his Dremel as he neatly cut the bottom of the downspout. We inserted the spout into the elbow joint that came with the rain barrel and screwed them together. Unfortunately, the elbow wasn't long enough to reliably deliver water to the barrel, so we took a short length of the trimmed downspout and attached that. This extended the spout all the way to the top of the rain barrel.

The modified downspout
The modified downspout
The downspout feeding the barrel
The downspout feeding the barrel

That was that. The rain barrel was ready to be filled. We had no idea when that would happen or how long it would take until a day or two later when it rained for a few hours, filling the rain barrel to overflowing. This was a bit of a problem as we hadn't yet redirected the overflow to something useful, so it just spilled out and washed away the topsoil I had been landscaping around the patio.

A full barrel
A full barrel
The washed away soil
The washed away soil

Overflow

Fortunately, we had two spare hoses. We had just bought a new garden hose to replace the two shorter ones that had come with the house. The best of these newly spare hoses was already destined to become the main outlet for the rain barrel, delivering lovely rain water down to the vegetables growing in our garden3. This left the second, leakier hose for me to use on the rain barrel overflow.

I attached the hose to the rain barrel, but where would it go. I didn't think having it draped across the lawn to the vegetable garden was really going to work and having the water just drain away seemed a bit of waste. So, I lay the hose out across the topsoil that was to form the flower bed next to the patio. Once I had reached the end of the bed, I cut the hose to length and discarded the remainder. I then proceeded to bury the hose along the bed, making sure to cut notches in it every few inches so that any overflow could irrigate the surrounding soil.

Cutting holes for irrigation
Cutting holes for irrigation
Rain barrel in place with overflow connected
Rain barrel in place with overflow connected

To finish things off, we purchased some white marble chips, rinsed them free of dust and distributed them on the lid of the rain barrel to discourage mosquitoes and other undesirable things from getting inside.

Finishing touches with a spot of marble
Finishing touches with a spot of marble

Where can I get one?

I hope the tales of our rain barrel have inspired you to get one (or more) of your own, they really are a great way to get some inexpensive fresh water to your garden. Look for someone in your area who is working to re-purpose food-grade containers just like Maxi Container and MI Rain Barrel are here in southeast Michigan. That way, you're not only going to conserve water but you'll also help to recycle these containers.

If you already have a rain barrel or are thinking of getting one, I'd love to hear about it.

  1. From this point on, just follow my wife's lead and assume "someone" is me. []
  2. Still me. []
  3. Chrissy has been tending a garden for a couple of years now, giving us some lovely fresh vegetables. []