Category Archives: Programming

TinyMCE Plugin: columns

tinymce.PluginManager.add("columns", function (editor) {
    function insert(count) {
        editor.undoManager.transact(function () {
            var row = editor.dom.create("div", { "class": "row" });
            var width = Math.ceil(12 / count);
            for (var index = 0; index < count; index++) {
                var column = editor.dom.add(row, "div", { "class": "col-sm-" + width });
                editor.dom.add(column, "p", {}, "Column " + (index + 1));
            }
            var node = editor.selection.getNode();
            if (node === editor.getBody()) {
                node = node.firstChild;
            }
            node.parentNode.insertBefore(row, node);
        });
    }

    function getMenuItem(text, count) {
        return {
            text: text,
            onclick: function () {
                insert(count);
            }
        };
    }

    var menu = [
        getMenuItem("Two", 2),
        getMenuItem("Three", 3),
        getMenuItem("Four", 4)
    ];
    editor.addMenuItem("columns", {
        text: "Insert columns",
        context: "insert",
        menu: menu
    });
});

TinyMCE Plugin: paragraphs

tinymce.PluginManager.add("paragraphs", function (editor) {
    function insert(place) {
        var body = editor.getBody();
        var paragraph = editor.dom.create("p");
        place(paragraph, body);
        editor.selection.setCursorLocation(paragraph);
        editor.nodeChanged();
    }

    editor.addMenuItem("paragraph", {
        text: "Insert paragraph",
        context: "insert",
        menu: [
            {
                text: "At top",
                onclick: function () {
                    insert(function (paragraph, body) {
                        body.insertBefore(paragraph, body.firstChild);
                    });
                }
            },
            {
                text: "At bottom",
                onclick: function () {
                    insert(function (paragraph, body) {
                        body.appendChild(paragraph);
                    });
                }
            }
        ]
    });
});

TinyMCE Plugin: glyphicons

tinymce.PluginManager.add("glyphicons", function (editor) {
    function insert(name) {
        editor.insertContent("<span class='glyphicon glyphicon-" + name + "'></span>");
    }

    function getMenuItem(name) {
        return {
            text: name,
            onclick: function () {
                insert(name);
            }
        };
    }

    editor.addMenuItem("glyphicons", {
        text: "Icon",
        context: "insert",
        menu: [
            getMenuItem("adjust"),
            getMenuItem("alert"),
            getMenuItem("align-center"),
            getMenuItem("align-justify"),
            getMenuItem("align-left"),
            getMenuItem("align-right"),
            getMenuItem("apple"),
            getMenuItem("arrow-down"),
            getMenuItem("arrow-left"),
            getMenuItem("arrow-right"),
            getMenuItem("arrow-up"),
            getMenuItem("asterisk"),
            getMenuItem("baby-formula"),
            getMenuItem("backward"),
            getMenuItem("ban-circle"),
            getMenuItem("barcode"),
            getMenuItem("bed"),
            getMenuItem("bell"),
            getMenuItem("bishop"),
            getMenuItem("bitcoin"),
            getMenuItem("blackboard"),
            getMenuItem("bold"),
            getMenuItem("book"),
            getMenuItem("bookmark"),
            getMenuItem("briefcase"),
            getMenuItem("btc"),
            getMenuItem("bullhorn"),
            getMenuItem("calendar"),
            getMenuItem("camera"),
            getMenuItem("cd"),
            getMenuItem("certificate"),
            getMenuItem("check"),
            getMenuItem("chevron-down"),
            getMenuItem("chevron-left"),
            getMenuItem("chevron-right"),
            getMenuItem("chevron-up"),
            getMenuItem("circle-arrow-down"),
            getMenuItem("circle-arrow-left"),
            getMenuItem("circle-arrow-right"),
            getMenuItem("circle-arrow-up"),
            getMenuItem("cloud"),
            getMenuItem("cloud-download"),
            getMenuItem("cloud-upload"),
            getMenuItem("cog"),
            getMenuItem("collapse-down"),
            getMenuItem("collapse-up"),
            getMenuItem("comment"),
            getMenuItem("compressed"),
            getMenuItem("console"),
            getMenuItem("copy"),
            getMenuItem("copyright-mark"),
            getMenuItem("credit-card"),
            getMenuItem("cutlery"),
            getMenuItem("dashboard"),
            getMenuItem("download"),
            getMenuItem("download-alt"),
            getMenuItem("duplicate"),
            getMenuItem("earphone"),
            getMenuItem("edit"),
            getMenuItem("education"),
            getMenuItem("eject"),
            getMenuItem("envelope"),
            getMenuItem("equalizer"),
            getMenuItem("erase"),
            getMenuItem("euro"),
            getMenuItem("exclamation-sign"),
            getMenuItem("expand"),
            getMenuItem("export"),
            getMenuItem("eye-close"),
            getMenuItem("eye-open"),
            getMenuItem("facetime-video"),
            getMenuItem("fast-backward"),
            getMenuItem("fast-forward"),
            getMenuItem("file"),
            getMenuItem("film"),
            getMenuItem("filter"),
            getMenuItem("fire"),
            getMenuItem("flag"),
            getMenuItem("flash"),
            getMenuItem("floppy-disk"),
            getMenuItem("floppy-open"),
            getMenuItem("floppy-remove"),
            getMenuItem("floppy-save"),
            getMenuItem("floppy-saved"),
            getMenuItem("folder-close"),
            getMenuItem("folder-open"),
            getMenuItem("font"),
            getMenuItem("forward"),
            getMenuItem("fullscreen"),
            getMenuItem("gbp"),
            getMenuItem("gift"),
            getMenuItem("glass"),
            getMenuItem("globe"),
            getMenuItem("grain"),
            getMenuItem("hand-down"),
            getMenuItem("hand-left"),
            getMenuItem("hand-right"),
            getMenuItem("hand-up"),
            getMenuItem("hd-video"),
            getMenuItem("hdd"),
            getMenuItem("header"),
            getMenuItem("headphones"),
            getMenuItem("heart"),
            getMenuItem("heart-empty"),
            getMenuItem("home"),
            getMenuItem("hourglass"),
            getMenuItem("ice-lolly"),
            getMenuItem("ice-lolly-tasted"),
            getMenuItem("import"),
            getMenuItem("inbox"),
            getMenuItem("indent-left"),
            getMenuItem("indent-right"),
            getMenuItem("info-sign"),
            getMenuItem("italic"),
            getMenuItem("jpy"),
            getMenuItem("king"),
            getMenuItem("knight"),
            getMenuItem("lamp"),
            getMenuItem("leaf"),
            getMenuItem("level-up"),
            getMenuItem("link"),
            getMenuItem("list"),
            getMenuItem("list-alt"),
            getMenuItem("lock"),
            getMenuItem("log-in"),
            getMenuItem("log-out"),
            getMenuItem("magnet"),
            getMenuItem("map-marker"),
            getMenuItem("menu-down"),
            getMenuItem("menu-hamburger"),
            getMenuItem("menu-left"),
            getMenuItem("menu-right"),
            getMenuItem("menu-up"),
            getMenuItem("minus"),
            getMenuItem("minus-sign"),
            getMenuItem("modal-window"),
            getMenuItem("move"),
            getMenuItem("music"),
            getMenuItem("new-window"),
            getMenuItem("object-align-bottom"),
            getMenuItem("object-align-horizontal"),
            getMenuItem("object-align-left"),
            getMenuItem("object-align-right"),
            getMenuItem("object-align-top"),
            getMenuItem("object-align-vertical"),
            getMenuItem("off"),
            getMenuItem("oil"),
            getMenuItem("ok"),
            getMenuItem("ok-circle"),
            getMenuItem("ok-sign"),
            getMenuItem("open"),
            getMenuItem("open-file"),
            getMenuItem("option-horizontal"),
            getMenuItem("option-vertical"),
            getMenuItem("paperclip"),
            getMenuItem("paste"),
            getMenuItem("pause"),
            getMenuItem("pawn"),
            getMenuItem("pencil"),
            getMenuItem("phone"),
            getMenuItem("phone-alt"),
            getMenuItem("picture"),
            getMenuItem("piggy-bank"),
            getMenuItem("plane"),
            getMenuItem("play"),
            getMenuItem("play-circle"),
            getMenuItem("plus"),
            getMenuItem("plus-sign"),
            getMenuItem("print"),
            getMenuItem("pushpin"),
            getMenuItem("qrcode"),
            getMenuItem("queen"),
            getMenuItem("question-sign"),
            getMenuItem("random"),
            getMenuItem("record"),
            getMenuItem("refresh"),
            getMenuItem("registration-mark"),
            getMenuItem("remove"),
            getMenuItem("remove-circle"),
            getMenuItem("remove-sign"),
            getMenuItem("repeat"),
            getMenuItem("resize-full"),
            getMenuItem("resize-horizontal"),
            getMenuItem("resize-small"),
            getMenuItem("resize-vertical"),
            getMenuItem("retweet"),
            getMenuItem("road"),
            getMenuItem("rub"),
            getMenuItem("ruble"),
            getMenuItem("save"),
            getMenuItem("save-file"),
            getMenuItem("saved"),
            getMenuItem("scale"),
            getMenuItem("scissors"),
            getMenuItem("screenshot"),
            getMenuItem("sd-video"),
            getMenuItem("search"),
            getMenuItem("send"),
            getMenuItem("share"),
            getMenuItem("share-alt"),
            getMenuItem("shopping-cart"),
            getMenuItem("signal"),
            getMenuItem("sort"),
            getMenuItem("sort-by-alphabet"),
            getMenuItem("sort-by-alphabet-alt"),
            getMenuItem("sort-by-attributes"),
            getMenuItem("sort-by-attributes-alt"),
            getMenuItem("sort-by-order"),
            getMenuItem("sort-by-order-alt"),
            getMenuItem("sound-5-1"),
            getMenuItem("sound-6-1"),
            getMenuItem("sound-7-1"),
            getMenuItem("sound-dolby"),
            getMenuItem("sound-stereo"),
            getMenuItem("star"),
            getMenuItem("star-empty"),
            getMenuItem("stats"),
            getMenuItem("step-backward"),
            getMenuItem("step-forward"),
            getMenuItem("stop"),
            getMenuItem("subscript"),
            getMenuItem("subtitles"),
            getMenuItem("sunglasses"),
            getMenuItem("superscript"),
            getMenuItem("tag"),
            getMenuItem("tags"),
            getMenuItem("tasks"),
            getMenuItem("tent"),
            getMenuItem("text-background"),
            getMenuItem("text-color"),
            getMenuItem("text-height"),
            getMenuItem("text-size"),
            getMenuItem("text-width"),
            getMenuItem("th"),
            getMenuItem("th-large"),
            getMenuItem("th-list"),
            getMenuItem("thumbs-down"),
            getMenuItem("thumbs-up"),
            getMenuItem("time"),
            getMenuItem("tint"),
            getMenuItem("tower"),
            getMenuItem("transfer"),
            getMenuItem("trash"),
            getMenuItem("tree-conifer"),
            getMenuItem("tree-deciduous"),
            getMenuItem("triangle-bottom"),
            getMenuItem("triangle-left"),
            getMenuItem("triangle-right"),
            getMenuItem("triangle-top"),
            getMenuItem("unchecked"),
            getMenuItem("upload"),
            getMenuItem("usd"),
            getMenuItem("user"),
            getMenuItem("volume-down"),
            getMenuItem("volume-off"),
            getMenuItem("volume-up"),
            getMenuItem("warning-sign"),
            getMenuItem("wrench"),
            getMenuItem("xbt"),
            getMenuItem("yen"),
            getMenuItem("zoom-in"),
            getMenuItem("zoom-out")
        ]
    });
});

TinyMCE Plugin: revert

tinymce.PluginManager.add("revert", function (editor) {
    var content;
    editor.on("LoadContent", function () {
        content = editor.getContent();
    });
    editor.addMenuItem("revert", {
        text: "Revert changes",
        context: "file",
        onclick: function () {
            editor.undoManager.transact(function () {
                editor.setContent(content);
            });
        }
    });
});

jQuery/Bootstrap Widget: fileinput

<script type="text/html" id="file-input-template">
    <div class="input-group">
        <input type="text" readonly="readonly" class="form-control" />
        <label class="input-group-btn">
            <span class="btn btn-primary">
                Browse
                <input type="file" class="sr-only" />
            </span>
        </label>
    </div>
</script>

<script type="text/javascript">
    $.widget("scw.fileinput", {
        options: {
            id: "file",
            name: "file",
            disabled: false
        },

        _create: function () {
            var self = this;
            self.$group = $($("#file-input-template").html()).appendTo(self.element);
            self.$file = self.$group.find("input[type='file']");
            self.$file.attr("id", self.options.id);
            self.$file.attr("name", self.options.name);
            self.$text = self.$group.find("input[type='text']");
            self.$button = self.$group.find(".btn");
            self._setDisabled(self.options.disabled);
            self.$file.change(function () {
                self.$text.val(self.$file.val());
            });
        },

        _setDisabled: function (disabled) {
            var self = this;
            self.$text.prop("disabled", disabled);
            self.$file.prop("disabled", disabled);
            self.$button.toggleClass("disabled", disabled);
        },

        _setOption: function (key, value) {
            var self = this;
            self._super(key, value);
            if (key === "disabled") {
                self._setDisabled(value);
            }
        }
    });
</script>

jQuery/Bootstrap Widget: dialog

<script type="text/html" id="modal-template">
    <div class="modal fade">
        <div class="modal-dialog">
            <div class="modal-content">
                <div class="modal-header">
                    <span class="modal-title"></span>
                </div>
                <div class="modal-body"></div>
                <div class="modal-footer"></div>
            </div>
        </div>
    </div>
</script>

<script type="text/javascript">
    $.widget("scw.dialog", {
        options: {
            size: "sm",
            title: "",
            body: "",
            buttons: [
                {
                    style: "primary",
                    text: "OK"
                }
            ]
        },

        _create: function () {
            var self = this;
            self.$modal = $($("#modal-template").html()).appendTo(self.element);
            self.$modal.find(".modal-dialog").addClass("modal-" + self.options.size);
            self.$modal.find(".modal-title").text(self.options.title);
            self.$modal.find(".modal-body").html(self.options.body);
            var $footer = self.$modal.find(".modal-footer");
            $.each(self.options.buttons, function () {
                var defaults = {
                    command: $.noop,
                    argument: null
                };
                var options = $.extend(defaults, this);
                var $button = $("<button type='button' class='btn'></button>");
                $button.addClass("btn-" + options.style);
                $button.text(options.text);
                $button.click(function () {
                    self.$modal.one("hidden.bs.modal", function () {
                        options.command(options.argument);
                        self.destroy();
                    });
                    self.$modal.modal("hide");
                });
                $footer.append($button);
            });
            self.$modal.modal({
                backdrop: "static",
                keyboard: false
            });
        },

        _destroy: function () {
            var self = this;
            self.$modal.remove();
        }
    });
</script>

Pixel-Perfect WPF Forms

App.xaml:

<Application x:Class="Test.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             StartupUri="MainWindow.xaml">
    <Application.Resources>
        <Style TargetType="CheckBox">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type CheckBox}">
                        <Border Padding="0,6,0,5">
                            <Grid x:Name="templateRoot" Background="Transparent" SnapsToDevicePixels="True">
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="Auto"/>
                                    <ColumnDefinition Width="*"/>
                                </Grid.ColumnDefinitions>
                                <Border x:Name="checkBoxBorder" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="1" VerticalAlignment="{TemplateBinding VerticalContentAlignment}">
                                    <Grid x:Name="markGrid">
                                        <Path x:Name="optionMark" Data="F1M9.97498,1.22334L4.6983,9.09834 4.52164,9.09834 0,5.19331 1.27664,3.52165 4.255,6.08833 8.33331,1.52588E-05 9.97498,1.22334z" Fill="#FF212121" Margin="1" Opacity="0" Stretch="None"/>
                                        <Rectangle x:Name="indeterminateMark" Fill="#FF212121" Margin="2" Opacity="0"/>
                                    </Grid>
                                </Border>
                                <ContentPresenter x:Name="contentPresenter" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" Grid.Column="1" ContentStringFormat="{TemplateBinding ContentStringFormat}" Focusable="False" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                            </Grid>
                        </Border>
                        <ControlTemplate.Triggers>
                            <Trigger Property="HasContent" Value="True">
                                <Setter Property="FocusVisualStyle">
                                    <Setter.Value>
                                        <Style>
                                            <Setter Property="Control.Template">
                                                <Setter.Value>
                                                    <ControlTemplate>
                                                        <Rectangle Margin="14,0,0,0" SnapsToDevicePixels="True" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" StrokeThickness="1" StrokeDashArray="1 2"/>
                                                    </ControlTemplate>
                                                </Setter.Value>
                                            </Setter>
                                        </Style>
                                    </Setter.Value>
                                </Setter>
                                <Setter Property="Padding" Value="4,-1,0,0"/>
                            </Trigger>
                            <Trigger Property="IsMouseOver" Value="True">
                                <Setter Property="Background" TargetName="checkBoxBorder" Value="#FFF3F9FF"/>
                                <Setter Property="BorderBrush" TargetName="checkBoxBorder" Value="#FF5593FF"/>
                                <Setter Property="Fill" TargetName="optionMark" Value="#FF212121"/>
                                <Setter Property="Fill" TargetName="indeterminateMark" Value="#FF212121"/>
                            </Trigger>
                            <Trigger Property="IsEnabled" Value="False">
                                <Setter Property="Background" TargetName="checkBoxBorder" Value="#FFE6E6E6"/>
                                <Setter Property="BorderBrush" TargetName="checkBoxBorder" Value="#FFBCBCBC"/>
                                <Setter Property="Fill" TargetName="optionMark" Value="#FF707070"/>
                                <Setter Property="Fill" TargetName="indeterminateMark" Value="#FF707070"/>
                            </Trigger>
                            <Trigger Property="IsPressed" Value="True">
                                <Setter Property="Background" TargetName="checkBoxBorder" Value="#FFD9ECFF"/>
                                <Setter Property="BorderBrush" TargetName="checkBoxBorder" Value="#FF3C77DD"/>
                                <Setter Property="Fill" TargetName="optionMark" Value="#FF212121"/>
                                <Setter Property="Fill" TargetName="indeterminateMark" Value="#FF212121"/>
                            </Trigger>
                            <Trigger Property="IsChecked" Value="True">
                                <Setter Property="Opacity" TargetName="optionMark" Value="1"/>
                                <Setter Property="Opacity" TargetName="indeterminateMark" Value="0"/>
                            </Trigger>
                            <Trigger Property="IsChecked" Value="{x:Null}">
                                <Setter Property="Opacity" TargetName="optionMark" Value="0"/>
                                <Setter Property="Opacity" TargetName="indeterminateMark" Value="1"/>
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

        <Style TargetType="RadioButton">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type RadioButton}">
                        <Border Padding="0,6,0,5">
                            <Grid x:Name="templateRoot" Background="Transparent" SnapsToDevicePixels="True">
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="Auto"/>
                                    <ColumnDefinition Width="*"/>
                                </Grid.ColumnDefinitions>
                                <Border x:Name="radioButtonBorder" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" CornerRadius="100" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="2,1" VerticalAlignment="{TemplateBinding VerticalContentAlignment}">
                                    <Grid x:Name="markGrid" Margin="2">
                                        <Ellipse x:Name="optionMark" Fill="#FF212121" MinWidth="6" MinHeight="6" Opacity="0"/>
                                    </Grid>
                                </Border>
                                <ContentPresenter x:Name="contentPresenter" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" Grid.Column="1" ContentStringFormat="{TemplateBinding ContentStringFormat}" Focusable="False" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                            </Grid>
                        </Border>
                        <ControlTemplate.Triggers>
                            <Trigger Property="HasContent" Value="True">
                                <Setter Property="FocusVisualStyle">
                                    <Setter.Value>
                                        <Style>
                                            <Setter Property="Control.Template">
                                                <Setter.Value>
                                                    <ControlTemplate>
                                                        <Rectangle Margin="14,0,0,0" SnapsToDevicePixels="True" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" StrokeThickness="1" StrokeDashArray="1 2"/>
                                                    </ControlTemplate>
                                                </Setter.Value>
                                            </Setter>
                                        </Style>
                                    </Setter.Value>
                                </Setter>
                                <Setter Property="Padding" Value="4,-1,0,0"/>
                            </Trigger>
                            <Trigger Property="IsMouseOver" Value="True">
                                <Setter Property="Background" TargetName="radioButtonBorder" Value="#FFF3F9FF"/>
                                <Setter Property="BorderBrush" TargetName="radioButtonBorder" Value="#FF5593FF"/>
                                <Setter Property="Fill" TargetName="optionMark" Value="#FF212121"/>
                            </Trigger>
                            <Trigger Property="IsEnabled" Value="False">
                                <Setter Property="Background" TargetName="radioButtonBorder" Value="#FFE6E6E6"/>
                                <Setter Property="BorderBrush" TargetName="radioButtonBorder" Value="#FFBCBCBC"/>
                                <Setter Property="Fill" TargetName="optionMark" Value="#FF707070"/>
                            </Trigger>
                            <Trigger Property="IsPressed" Value="True">
                                <Setter Property="Background" TargetName="radioButtonBorder" Value="#FFD9ECFF"/>
                                <Setter Property="BorderBrush" TargetName="radioButtonBorder" Value="#FF3C77DD"/>
                                <Setter Property="Fill" TargetName="optionMark" Value="#FF212121"/>
                            </Trigger>
                            <Trigger Property="IsChecked" Value="True">
                                <Setter Property="Opacity" TargetName="optionMark" Value="1"/>
                            </Trigger>
                            <Trigger Property="IsChecked" Value="{x:Null}">
                                <Setter Property="Opacity" TargetName="optionMark" Value="0.56"/>
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

        <Style TargetType="TextBox">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type TextBoxBase}">
                        <Border Padding="0,2">
                            <Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Padding="2" SnapsToDevicePixels="True">
                                <ScrollViewer x:Name="PART_ContentHost" Focusable="False" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden"/>
                            </Border>
                        </Border>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsEnabled" Value="False">
                                <Setter Property="Opacity" TargetName="border" Value="0.56"/>
                            </Trigger>
                            <Trigger Property="IsMouseOver" Value="True">
                                <Setter Property="BorderBrush" TargetName="border" Value="#FF7EB4EA"/>
                            </Trigger>
                            <Trigger Property="IsKeyboardFocused" Value="True">
                                <Setter Property="BorderBrush" TargetName="border" Value="#FF569DE5"/>
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Application.Resources>
</Application>

MainWindow.xaml:

<Window x:Class="Test.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Height="300"
        Title="Test"
        Width="400">
    <StackPanel Margin="10">
        <Label>Test</Label>
        <TextBox>Test</TextBox>
        <CheckBox>Test</CheckBox>
        <RadioButton>Test</RadioButton>
        <StackPanel Orientation="Horizontal">
            <Label>Test</Label>
            <TextBox>Test</TextBox>
        </StackPanel>
        <StackPanel Orientation="Horizontal">
            <CheckBox Margin="0,0,5,0">Test</CheckBox>
            <TextBox>Test</TextBox>
        </StackPanel>
        <StackPanel Orientation="Horizontal">
            <CheckBox Margin="0,0,5,0">Test</CheckBox>
            <TextBox>Test</TextBox>
            <Label>Test</Label>
        </StackPanel>
        <StackPanel Orientation="Horizontal">
            <RadioButton Margin="0,0,5,0">Test</RadioButton>
            <TextBox>Test</TextBox>
        </StackPanel>
        <StackPanel Orientation="Horizontal">
            <RadioButton Margin="0,0,5,0">Test</RadioButton>
            <TextBox>Test</TextBox>
            <Label>Test</Label>
        </StackPanel>
    </StackPanel>
</Window>

Before:

After:

WPF Application Boilerplate

using System;
using System.Text;
using System.Windows;

public partial class App : Application
{
    [STAThread]
    private static void Main(string[] args)
    {
        try
        {
            App app = new App();
            app.Run();
        }
        catch (Exception ex)
        {
            HandleError(ex);
        }
    }

    private static void HandleError(Exception ex)
    {
        Clipboard.SetText(ex.ToString());
        StringBuilder message = new StringBuilder();
        message.AppendLine("The application has encountered an error and must shut down.");
        message.AppendLine();
        message.AppendLine(string.Format("{0}: {1}", ex.GetType(), ex.Message));
        message.AppendLine();
        message.Append("Full details have been copied to the clipboard.");
        MessageBox.Show(message.ToString(), "Error", MessageBoxButton.OK, MessageBoxImage.Error);
    }

    public App()
    {
        DispatcherUnhandledException += (sender, e) =>
        {
            HandleError(e.Exception);
            e.Handled = true;
            Shutdown(1);
        };
        InitializeComponent();
    }

    protected override void OnStartup(StartupEventArgs e)
    {
        base.OnStartup(e);
        Window window/* = ... */;
        window.Show();
    }
}

Update: April 5, 2018

For something a little less user-hostile, save the stack trace to a temporary file instead of the clipboard:

private static void HandleError(Exception ex)
{
    string path = Path.GetTempFileName();
    File.WriteAllText(path, ex.ToString());
    StringBuilder message = new StringBuilder();
    message.AppendLine("The application has encountered an error and must shut down.");
    message.AppendLine();
    message.AppendLine(string.Format("{0}: {1}", ex.GetType(), ex.Message));
    message.AppendLine();
    message.AppendLine("Full details have been saved to the following file:");
    message.AppendLine();
    message.Append(path);
    MessageBox.Show(message.ToString(), "Error", MessageBoxButton.OK, MessageBoxImage.Error);
}

Compacting Paths

using System.Runtime.InteropServices;
using System.Text;

public static class Shlwapi
{
    [DllImport("shlwapi.dll")]
    public static extern bool PathCompactPathEx(StringBuilder pszOut, string pszSrc, uint cchMax, uint dwFlags);

    public static string CompactPath(string path, int length)
    {
        StringBuilder builder = new StringBuilder(length + 1);
        PathCompactPathEx(builder, path, (uint)length + 1, 0);
        return builder.ToString();
    }
}

Messing with Message Loops

using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Threading;
using System.Windows.Forms;

public class MessageLoop
{
    private Thread thread;
    private SynchronizationContext context;
    private ManualResetEvent initialized;

    public MessageLoop()
    {
        thread = new Thread(Initialize);
        thread.SetApartmentState(ApartmentState.STA);
        initialized = new ManualResetEvent(false);
    }

    private void Initialize()
    {
        Application.Idle += Application_Idle;
        Application.Run();
    }

    private void Application_Idle(object sender, EventArgs e)
    {
        if (Thread.CurrentThread.ManagedThreadId != thread.ManagedThreadId)
        {
            return;
        }
        Application.Idle -= Application_Idle;
        context = SynchronizationContext.Current;
        initialized.Set();
    }

    public void Start()
    {
        thread.Start();
        initialized.WaitOne();
    }

    public void Post(Action action)
    {
        context.Post(obj => action(), null);
    }

    public void Send(Action action)
    {
        context.Send(obj => action(), null);
    }

    public void Stop()
    {
        Send(() => Application.ExitThread());
        thread.Join();
    }
}

internal static class Program
{
    private const string Url = "http://www.stevencwilliams.com/";
    private static readonly string Path = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "screenshot.png");
    private static readonly Size Size = new Size(640, 480);
    private static readonly TimeSpan Timeout = TimeSpan.FromSeconds(0.1);

    private static ManualResetEvent done;
    private static Bitmap screenshot;

    private static void Main(string[] args)
    {
        File.Delete(Path);
        done = new ManualResetEvent(false);
        MessageLoop loop = new MessageLoop();
        loop.Start();
        loop.Send(Download);
        Wait();
        loop.Stop();
        if (done.WaitOne(TimeSpan.Zero))
        {
            screenshot.Save(Path);
        }
    }

    private static void Download()
    {
        WebBrowser browser = new WebBrowser()
        {
            Width = Size.Width,
            Height = Size.Height,
            ScriptErrorsSuppressed = true
        };
        browser.DocumentCompleted += (sender, e) =>
        {
            screenshot = new Bitmap(Size.Width, Size.Height);
            browser.DrawToBitmap(screenshot, new Rectangle(0, 0, Size.Width, Size.Height));
            done.Set();
        };
        browser.Navigate(Url);
        Console.WriteLine("Downloading {0}...", Url);
    }

    private static void Wait()
    {
        Console.WriteLine("Press any key to cancel...");
        foreach (char spinner in GetSpinners())
        {
            try
            {
                Console.Write(spinner);
                if (done.WaitOne(Timeout) || Console.KeyAvailable)
                {
                    break;
                }
            }
            finally
            {
                Console.Write('\b');
            }
        }
    }

    private static IEnumerable<char> GetSpinners()
    {
        while (true)
        {
            yield return '|';
            yield return '/';
            yield return '-';
            yield return '\\';
        }
    }
}