Nick Kramer on selling your boss on WPF

Nick Kramer posted this item late last year on “selling your boss on WPF”. The key points for me were that WPF allows you to create a great user-experience for your apps, and that WPF is coming soon. Because it was first announced at PDC 2003 it seems like its been “coming soon” forever, but soon in this context probably means “this year” (2006). »

WPF Spell Checking

Richard Bailey of the Cider team shows how simple it is to add spell-checking to your WPF TextBox and RichTextBox controls. Just set IsSpellCheckEnabled=”True” and your uses will see red squigglies when they mis-type a word! Right-clicking also provides a list of suggestions. Even cooler is that this is WPFs own spell-checking engine, and does not rely on MS Word. It does not contain a grammar checker. »

Office12 'LivePreview' feature implemented in WPF

To try to get “out of my comfort zone” (which is pretty small to begin with) in WPF I decided to try and emulate some of the UI enhancements I’ve heard about in Office 12. One of them is called “live preview” which shows you in real-time what potential changes (like increasing the font size, making something bold etc) will look like in your document as you you mouse over things. I implemented a “live preview” of the font changing. This was cool because I got to implement a font-selection dialog in WPF (creating a collection of system fonts and binding it to a dropdown list in WPF took about 5 lines of C# and 3 lines of XAML), and play with a few styles and such. In addition to this I had a look at manipulating the super-flexible WPF RichTextBox. I’m pretty sure if you didn’t care about interoperability with MSWord you could build a fully-featured word processor using this control in a few days. One challenge was that none of the WPF UI elements provide a “hover” event (the font is only supposed to update if you hover over the same item for a little while). I had to fake it (poorly) using a timer. There are a few other glaring imperfections too - for example if you “preview” a font change but then don’t actually select anything then your document DOESN’T go back to the way it was before…but hey - its a demo.
font selection dropdown list selecting some fonts ala Office12 LivePreview

The reason the font dropdown list is so wide is because some of the names of the crazy fonts I installed to play around with this feature. There is a video of it in action also here [180 KB].

Here is the XAML (for the Dec 05 CTP):

<?Mapping XmlNamespace=“urn:JCooney.Net.SeeingIsBelieving” ClrNamespace=“SeeingIsBelieving” ?>
<Window x:Class=“SeeingIsBelieving.Window1”
    xmlns=“http://schemas.microsoft.com/winfx/avalon/2005"
    xmlns:x=“http://schemas.microsoft.com/winfx/xaml/2005"
    xmlns:local=“urn:JCooney.Net.SeeingIsBelieving”
    Title=“SeeingIsBelieving”
    Loaded=“mainWindowLoaded”
    Width=“450”
    Height=“200”
    >
  <Window.Resources>
    <local:FontNameList x:Key=“InstalledFonts”/>
    <DataTemplate x:Key=“FontComboTemplate”>
      <TextBlock Text=“{Binding}” FontFamily=“{Binding}” MouseEnter=“fontSelectionMouseEnter”></TextBlock>
    </DataTemplate>
    <LinearGradientBrush x:Key=“SelectedItemBackground” StartPoint=“0,0” EndPoint=“0,1”>
      <LinearGradientBrush.GradientStops>
        <GradientStop Color=“#e0e4ee” Offset=“0.1”/>
        <GradientStop Color=“#c7d1e4” Offset=“0.4”/>
        <GradientStop Color=“#acbbd9” Offset=“0.5”/>
        <GradientStop Color=“#d5dcec” Offset=“0.95”/>
      </LinearGradientBrush.GradientStops>
    </LinearGradientBrush>
    <Style TargetType=“{x:Type ComboBoxItem}”>
      <Setter Property=“BorderThickness” Value=“1” />
      <Style.Triggers>
        <Trigger Property=“IsMouseOver” Value=“True”>
          <Setter Property=“Background” Value=“{StaticResource SelectedItemBackground}”/>
          <Setter Property=“BorderBrush” Value=“Blue”/>
          <Setter Property=“Foreground” Value=“Black”/>
        </Trigger>
        <Trigger Property=“IsKeyboardFocused” Value=“True”>
          <Setter Property=“Background” Value=“{StaticResource SelectedItemBackground}”/>
          <Setter Property=“BorderBrush” Value=“Blue”/>
          <Setter Property=“Foreground” Value=“Black”/>
        </Trigger>
      </Style.Triggers>
    </Style>
  </Window.Resources>
  <DockPanel LastChildFill=“True” >
    <DockPanel LastChildFill=“False” DockPanel.Dock=“Top”>
      <ComboBox DockPanel.Dock=“Right” x:Name=“fontComboBox”
        FontSize=“20”
        MouseLeave=“fontComboMouseLeave”
        SelectionChanged=“fontComboSelectionChanged”
        ItemsSource=“{StaticResource InstalledFonts}”
        ItemTemplate=“{StaticResource FontComboTemplate}”/>
      <TextBlock DockPanel.Dock=“Right”>Fonts:</TextBlock>
    </DockPanel>
    <Border BorderBrush=“Navy” CornerRadius=“5” BorderThickness=“2”>
    <RichTextBox x:Name=“testInput” AcceptsReturn=“True” Padding=“10,10,10,10” FontSize=“20”>
      <FlowDocument>
        <Paragraph>The quick brown fox jumps over the lazy dog.</Paragraph>
      </FlowDocument>
    </RichTextBox>
    </Border>
</DockPanel> </Window>

Here is the C# (also for the Dec 05 CTP)

using System;
using System.Drawing;
using System.Drawing.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

namespace SeeingIsBelieving { ///

/// Interaction logic for Window1.xaml /// public partial class Window1 : Window { System.Windows.Threading.DispatcherTimer _hoverTimer = new System.Windows.Threading.DispatcherTimer(); string _fontFamilyName; public Window1() { InitializeComponent(); } void Window1_Loaded(object sender, RoutedEventArgs e) { } private void mainWindowLoaded(object sender, RoutedEventArgs e) { _hoverTimer.Interval = new TimeSpan(0, 0, 0, 2); _hoverTimer.Tick += new EventHandler(_hoverTimerTick); } void _hoverTimerTick(object sender, EventArgs e) { SetTextSelectionFont(_fontFamilyName); } private void SetTextSelectionFont(string fontFamilyName) { System.Windows.Media.FontFamily f = new System.Windows.Media.FontFamily(fontFamilyName); testInput.Selection.ApplyPropertyValue(TextElement.FontFamilyProperty, f); } private void fontSelectionMouseEnter(object sender, RoutedEventArgs e) { TextBlock t = (TextBlock)sender; _fontFamilyName = t.Text; _hoverTimer.IsEnabled = false; _hoverTimer.IsEnabled = true; } private void fontComboSelectionChanged(object sender, RoutedEventArgs e) { SetTextSelectionFont((string)fontComboBox.SelectedItem); } private void fontComboMouseLeave(object sender, RoutedEventArgs e) { _hoverTimer.IsEnabled = false; } } public class FontNameList : System.Collections.Generic.List { public FontNameList() { using (InstalledFontCollection fonts = new InstalledFontCollection()) { foreach (System.Drawing.FontFamily f in fonts.Families) { base.Add(f.Name); } } } } }

Comments

JosephCooney
That should be "a font-selection drop-down" not "a font-selection dialog". I would change it except .Text/FreeTextBox drops all my XAML formatting when I try to do so.
11/01/2006 4:50:00 AM

»

Office 12 UI Video from Jensen Harris & BayCHI

I just finished watching the video of the presentation Jensen Harris gave at the BayCHI regarding the new Office 12 UI. The talk is well worth watching, especially for the demonstrations. The core tennents of the Office UI design team were worth repeating (or at least paraphrasing): Help people work without interference Increase the user’s sense of mastery through contextualization increase efficient access to features Consistency, but not homogeneity Give features a permanent home. »

Vices

After a stint going coffee-free a few months back I’m now back on the good stuff. Worryingly at almost every team meeting I go to the state of my caffeination is discussed, phrases like “you’re not off coffee again are you” are thrown around in concerned tones. Me going cold-turkey again hasn’t quite made it into the risks spreadsheet yet, but it is not far off. I’m probably the last person to have seen this great set of photos entitled espresso porn (totally worksafe, but you may need to go and get a coffee right after seeing these) - they make me want to reach for another cup right now. A co-worker also sent me a link to this coffee related photo which they said “reminded them of me”. Speaking of vices I’m sure as the new year rolls around I’m not alone in wondering if the secretgeek Leon Bambrick has achieved his goal for 2005 and taken up smoking. I have it on good authority from Angus “no consulting before 9:00 AM” Logan that he has been known to when in an inebriated state.

Comments

jayson knight
Caffeine free for almost a year now over here…in the words of a fellow developer I worked with who (when I first got the job) offered to fetch me a cup of coffee:

"You don’t drink coffee? So how does it feel to be the most awake at 8am that you’ll feel for the entire day?"


I don’t miss it a bit though…but I’m probably one of the few devs on the planet who doesn’t have a caffiene fix :-).
2/01/2006 1:13:00 AM
Angus Logan
Dude you seriously can’t consult before 9am.

Its the law.

I’ll write a post later on explaining why you can’t :)

and yeah - secretGeek was smoking like a madman at his resignation party :)
2/01/2006 3:33:00 PM

»

List of httperr log file reason phrases

I recently discovered this list of reason codes, their explanation and in some cases the HTTP code that is returned for IIS6’s httperr log files. Httperr log files are new to IIS6, are usually stored in c:\windows\system32\logfiles\ directory and contain interesting information you don’t see in your regular IIS log files. As the name suggests they only contain “error” information (not information about every single request), and are more low-level. For example if a site is disabled, or if the app-pool is recycled then that information gets logged there. »

Is learning XAML a waste of time?

I’ve been spending most of my spare time playing around with WPF, which usually means jumping in and writing XAML code in a text editor like visual studio 2005. Aside from mobiform’s aurora product which I really should have a good look at some time soon (and the option to export static XAML from illustrator and acrylic) there aren’t any XAML design tools out there (Microsoft’s two tools code-named sparkle and cider are yet to be released). »