Monday, 22 October 2012

Listing Font Names in Windows 8 C# XAML Apps

I thought this would be a two line job, but as often in Windows 8, things aren't always as you'd expect. All I wanted to do was list font names for a combo box picker, but found you need to use DirectX DirectWrite to get the font names.

There's an example of doing this in an HTML/JS app using a C++ interop here:

http://code.msdn.microsoft.com/windowsapps/DirectWrite-font-60e53e0b

I can't really beleive we need to go to such lengths to do something so simple, but luckily SharpDX comes to the rescue (again). It's still a bit convoluted having to interrogate the DirectWrite font family collections, but loads easier than writing a C++ interop!

Here's a helper class I wrote to get font names:


using SharpDX.DirectWrite;
using System.Collections.Generic;
using System.Linq;

namespace WebberCross.Helpers
{
    public class FontHelper
    {
        public static IEnumerable<string> GetFontNames()
        {
            var fonts = new List<string>();

            // DirectWrite factory
            var factory = new Factory();

            // Get font collections
            var fc = factory.GetSystemFontCollection(false);

            for (int i = 0; i < fc.FontFamilyCount; i++)
            {
                // Get font family and add first name
                var ff = fc.GetFontFamily(i);

                var name = ff.FamilyNames.GetString(0);
                fonts.Add(name);
            }

            // Always dispose DirectX objects
            factory.Dispose();

            return fonts.OrderBy(f => f);
        }
    }
}

Tuesday, 9 October 2012

Using a ManualResetEvent To Stop A Console Application From Terminating


This is a quick example of how to use a ManualResetEvent to stop a console application from terminating whilst an event driven (or callback driven) asynchronous process is busy.




Basically a ManualResetEvent is waited on at the end of the main method until it is signalled to complete by one of the events:

using System;
using System.Threading;

namespace ConsoleApplicationWait
{
  class Program
  {
    static ManualResetEvent _mre = new ManualResetEvent(false);
    static EventSource _src = new EventSource();

    static void Main(string[] args)
    {
      _src.NewNumber += _src_NewNumber;
      _src.Finished += _src_Finished;

      // Starting events
      _src.Start();

      // Block main thread until signalled to continue
      Console.WriteLine("Reached the end of main method and waiting for signal...");
      _mre.WaitOne();

      Console.WriteLine("Signal received, press enter to exit...");
      Console.ReadLine();
    }

    static void _src_Finished(object sender, EventArgs e)
    {
      Console.WriteLine("Finished event received, signalling all done");

      // Signal wait handle to continue
      _mre.Set();
    }

    static void _src_NewNumber(object sender, NumberEventArgs e)
    {
      Console.WriteLine(e.Number);
    }
  }

  /// <summary>
  /// Simple number eventargs
  /// </summary>
  public class NumberEventArgs : EventArgs
  {
    public int Number { get; set; }

    public NumberEventArgs(int number)
    {
      this.Number = number;
    }
  }

  /// <summary>
  /// Class to simulate something which generates a number of events
  /// </summary>
  public class EventSource
  {
    public event EventHandler<NumberEventArgs> NewNumber;
    public event EventHandler Finished;

    public void Start()
    {
      Thread t = new Thread(new ThreadStart(() =>
        {
          for (int i = 0; i < 10; i++)
          {
            if (this.NewNumber != null)
              this.NewNumber(this, new NumberEventArgs(i));

            // 1s delays so we can see what's going on
            Thread.Sleep(1000);
          }

          if (this.Finished != null)
            this.Finished(this, new EventArgs());
        }));

      t.Start();
    }
  }
}

Thursday, 4 October 2012

Windows 8 ItemTapCommand Attached Property

This attached property picks up touch tap events from FrameworkElements and triggers an attached command. This is useful for controls like GridViews where you might click an item or tap it to perform an action.


public class ItemTapCommand
{
  public static readonly DependencyProperty CommandProperty =
            DependencyProperty.RegisterAttached("Command", typeof(ICommand), typeof(ItemTapCommand), new PropertyMetadata(null, CommandPropertyChanged));

  public static void SetCommand(DependencyObject attached, ICommand value)
  {
    attached.SetValue(CommandProperty, value);
  }

  public static ICommand GetCommand(DependencyObject attached)
  {
    return (ICommand)attached.GetValue(CommandProperty);
  }

  private static void CommandPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  {
    // Attach tap handler
    (d as FrameworkElement).Tapped += ItemTapCommand_Tapped;
  }
       
  private static void ItemTapCommand_Tapped(object sender, Windows.UI.Xaml.Input.TappedRoutedEventArgs e)
  {
    // Get command
    ICommand command = GetCommand(sender as DependencyObject);

    // Execute command
    command.Execute(null);
  }
}

This example shows it attached to a GridView item (grid) and using a command from the view model via the context of the GridView:

<GridView ItemsSource="{Binding Items}"
  SelectedItem="{Binding SelectedItem, Mode=TwoWay}" SelectionMode="Single">
  <GridView.ItemTemplate>
    <DataTemplate>
      <Grid Width="133" Height="200"
cmd:ItemTapCommand.Command="{Binding ElementName=posterGrid, Path=DataContext.EditCommand}">