Category Archives: XAML

Is your Universal Windows application running on a device which supports this hardware ?

Just going through some old draft posts and found this one, which might be of use to somebody. Let’s call it a Quick Post as there’s not too much substance…

When writing a Universal Windows application we’re basically trying to write code that will work on multiple devices. But different devices have different capabilities. For example a mobile phone has a back button, so we might want to handle the back button BackPressed event in some way, but this event is not available when the application is run on a desktop machine.

Obviously it’d be no good using #define to enable/disable code as we want the application’s code to be universal and run “as-is” on multiple devices. So we need a method call at runtime to tell us whether the device supports the BackButton. Or more specifically whether it supports the HardwareButtons input mechanism.

So to check whether we can hook up code to the BackPressed event we might code the following

if(ApiInformation.IsTypePresent("Windows.Phone.UI.Input.HardwareButtons"))
{
   HardwareButtons.BackPressed += HandleBackPressed;
}

Turning XAML into objects using XamlReader

I couldn’t come up with a good title for this post, basically the post is about taking a XAML declared Style and finding the easiest way to turn this into a Style object in code.

I had a problem whereby I ended up with multiple style objects which were exactly the same except for the DataItem they were binding to. This ended up meaning I had lots of duplicate XAML code, apart from one difference. Once I started making the code more dynamic (it was adding columns to the Infragistics XamDataGrid) this XAML became almost useless as I needed to create a style for each dynamically added column and hence really need to generate the Style in code.

If you’ve done anything much with code behind for such things as creating Style objects or replicating XAML code you’ve probably found the code doesn’t always map directly to the XAML, and if you already have XAML that works, why not simply reused it.

Note: The reason the code doesn’t always map is that it includes resources, converters and other XAML magically things that are automatically applied, for example converting colour names to colour values, or field lengths etc.

So let’s simple copy our XAML into a string in code and then programmatically change the DataItem field and then generate our Style object from this.

Here’s an example of the XAML as a string

var styleString = 
   "<Style TargetType=\"{x:Type idp:CellValuePresenter}\">" +
   "<Setter Property=\"Template\">" +
   "<Setter.Value>" +
   "<ControlTemplate>" +
   "<Grid>" +
   "<ListBox ItemsSource=\"{Binding DataItem." + source + "}\">" +
   "<ListBox.ItemTemplate>" +
   "<DataTemplate>" +
   "<TextBlock HorizontalAlignment=\"Stretch\" Text=\"{Binding}\"/>" +
   "</DataTemplate>" +
   "</ListBox.ItemTemplate>" +
   "<ListBox.ItemsPanel>" +
   "<ItemsPanelTemplate>" +
   "<StackPanel Orientation=\"Vertical\"/>" +
   "</ItemsPanelTemplate>" +
   "</ListBox.ItemsPanel>" +
   "</ListBox>" +
   "</Grid>" +
   "</ControlTemplate>" +
   "</Setter.Value>" +
   "</Setter>" +
   "</Style>";

In the above we’d obviously supply the source variable and this will then form part of our XAML style. To turn this into a Style object we need to use the XamlReader.Parse method. Before we can use the XamlReader.Parse method we also need to create the namespaces (context items) that we would expect from our XAML code, in this case we create a ParseContent object and assign our namespaces, then pass this into the XamlReader.Parse method also with the styleString. Our code might look like the following

public Style CreateStyle(string source)
{
   var context = new ParserContext();
   context.XmlnsDictionary.Add
   ("", 
    "http://schemas.microsoft.com/winfx/2006/xaml/presentation");
   context.XmlnsDictionary.Add
   ("x", 
    "http://schemas.microsoft.com/winfx/2006/xaml");

   // other namespaces for XamaDataGrid etc.

   var styleString = 
      "<Style TargetType=\"{x:Type dataPresenter:CellValuePresenter}\">" +
      "<Setter Property=\"Template\">" +
      "<Setter.Value>" +
      "<ControlTemplate>" +
      "<Grid>" +
      "<ListBox ItemsSource=\"{Binding DataItem." + source + "}\">" +
      "<ListBox.ItemTemplate>" +
      "<DataTemplate>" +
      "<TextBlock HorizontalAlignment=\"Stretch\" Text=\"{Binding}\"/>" +
      "</DataTemplate>" +
      "</ListBox.ItemTemplate>" +
      "<ListBox.ItemsPanel>" +
      "<ItemsPanelTemplate>" +
      "<StackPanel Orientation=\"Vertical\"/>" +
      "</ItemsPanelTemplate>" +
      "</ListBox.ItemsPanel>" +
      "</ListBox>" +
      "</Grid>" +
      "</ControlTemplate>" +
      "</Setter.Value>" +
      "</Setter>" +
      "</Style>";

   return (Style)XamlReader.Parse(styleString, context);
}

That’s it – much simpler that create each piece of the Style using C# objects and allows us to first test our XAML out then reused it to generate our objects in code.

Note: If your code relied on namespaces/assemblies which are not already loaded you will have to load them into memory yourself before they can be used in this way.

TypeConverters and XAML

When we’re setting margins, backgrounds etc. in XAML we use string representations which get converted to the actual objects. For example

<Button Margin="0,3,0,3" />

in this example the string 0,3,0,3 is converted into a Margin object by the MarginConverter.

Strings are converted to types using TypeConverters. A simple example of one is listed below

public class AbbreviatedNumberConverter : TypeConverter
{
   public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
   {
      return sourceType == typeof(string) || base.CanConvertFrom(context, sourceType);
   }

   public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
   {
      return destinationType == typeof(InstanceDescriptor) || 
                 base.CanConvertTo(context, destinationType);
   }

   public override object ConvertFrom(ITypeDescriptorContext context, 
                            CultureInfo culture, object value)
   {
      string text = value as string;
      if (text == null)
      {
         return base.ConvertFrom(context, culture, value);
      }

      if (String.IsNullOrWhiteSpace(text))
      {
         return 0.0;
      }

      if (culture == null)
      {
         culture = CultureInfo.CurrentCulture;
      }

      double number;
      if (AbbreviatedNumeric.ValidateDouble(text, out number, culture))
         return number;

      return 0.0;
   }

   public override object ConvertTo(ITypeDescriptorContext context, 
                     CultureInfo culture, object value, Type destinationType)
   {
      if (destinationType != null && value is Double)
      {
         if (destinationType == typeof(string))
         {
            return value.ToString();
 	 }
      }
      return base.ConvertTo(context, culture, value, destinationType);
   }
}

So the above demonstrated a very simple TypeConverter that converts strings like “134m” into 134000000 or the likes of “10k” to 10000. The actual code for the conversion occurs in the AbbreviatedNumeric.ValidateDouble method which I’ll list at the end of this post but will exclude the tests just to save space. This is not an all encompassing converter, it will only convert k for thousands, m for millions and b for billions and also doesn’t handle multiple languages, but it’s here as an example.

Now let’s assume we’ve created some edit control which has an Amount dependency property which we want to allow the user to enter abbreviated numeric strings into. So the dependency property might look like

public Double Amount
{
   get { return (Double)GetValue(AmountProperty); }
   set { SetValue(AmountProperty, value); }
}

public static readonly DependencyProperty AmountProperty =
                    DependencyProperty.Register("Amount", typeof(Double), 
                    typeof(OnlineStatusControl), new PropertyMetadata(0.0));

To apply our type converter we simple add the TypeConverterAttribute to the Amount property as below

[TypeConverter(typeof(AbbreviatedNumberConverter))]
public Double Amount
{
   get { return (Double)GetValue(AmountProperty); }
   set { SetValue(AmountProperty, value); }
}

and finally when using this new control we can do the following

<Controls:AbbreviatedNumericEditor Amount="123m" />

The type converter is called on this and 123m is converted to 123000000 which is now stored as a Double in the dependency property Amount.

For completeness, here’s the simple AbbreviatedNumeric class

public static class AbbreviatedNumeric
{
   public static bool ValidateDouble(string value, out double? numeric, 
              CultureInfo cultureInfo = null)
   {
      double result;
      if(ValidateDouble(value, out result, cultureInfo))
      {
         numeric = result;
         return true;
      }
      numeric = null;
      return false;
   }

   public static bool ValidateDouble(string value, out double numeric, 
              CultureInfo cultureInfo = null)
   {	
      if (String.IsNullOrEmpty(value))
      {
         numeric = 0;
         return false;
      }

      if (Double.TryParse(value, out numeric))
      {
         return true;
      }
      if (value.Length > 0)
      {
         if (cultureInfo == null)
         {
	    cultureInfo = CultureInfo.CurrentCulture;
	 }

	 NumberFormatInfo numberFormat = cultureInfo.NumberFormat;
 	 if (value.Substring(0, 1) == numberFormat.NumberDecimalSeparator)
	 {
	    value = "0" + value;
	 }
	 if (Double.TryParse(value.Substring(0, value.Length - 1), 
                     NumberStyles.AllowLeadingWhite | 
                     NumberStyles.AllowTrailingWhite |                      
                     NumberStyles.AllowLeadingSign |
 		     NumberStyles.AllowDecimalPoint | 
                     NumberStyles.AllowThousands | 
		     NumberStyles.AllowExponent, cultureInfo, out numeric))
	 {
	    switch (Char.ToUpper(value[value.Length - 1]))
	    {
	        case 'B':
		   numeric = numeric * 1000000000;
		   break;
		case 'M':
		   numeric = numeric * 1000000;
		   break;
		case 'K':
		   numeric = numeric * 1000;
		   break;
		default:
		   return false;
	    }
            return true;
	 }
      }
      return false;
   }
}

MarkupExtension

The MarkupExtension is the base class for things like StaticResource, DynamicResource, Binding and so on. It basically allows derived classes to participate in XAML more like a first class citizen.

For example, everyone and their dog has written a BooleanToVisibilityConverter (or those less prone to reinventing the wheel will have used something similar from one of the many WPF/XAML frameworks). But for the sake of this post let’s create one again.

public class BooleanToVisibilityConverter : IValueConverter
{
   public object Convert(object value, Type targetType, object parameter,
                         CultureInfo culture)
   {
      bool result = (value is bool?) ?
                         ((bool?) value).GetValueOrDefault(false) :
                         false;
      if(value is bool)
      {
         result = (bool) value;
      }
      return result ? Visibility.Visible : Visibility.Collapsed;
   }

   public object ConvertBack(object value, Type targetType, object parameter,
                             CultureInfo culture)
   {
      return (value is Visibility) ? (Visibility) value == Visibility.Visible : false;
   }
}

Now to use this in XAML we need to declare it within a ResourceDictionary

<Controls:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />

and to use we do the following

<Button Content="Cancel" Visibility="{Binding IsCancelVisible, 
    Converter={StaticResource BooleanToVisibilityConverter}}" />


There’s absolutely nothing wrong with this approach, but we could alter things slightly by deriving the BooleanToVisibilityConverter from MarkupExtension as per the following

public class BooleanToVisibilityConverter : MarkupExtension, IValueConverter
{
   public override object ProvideValue(IServiceProvider serviceProvider)
   {
      return this;
   }

   // previous code unaltered
}

Now we can remove the entry from the ResourceDictionary and alter the usage in the XAML for the button declaration to

<Button Content="Cancel" Visibility="{Binding IsCancelVisible, 
   Converter={Controls:BooleanToVisibilityConverter}}">


Well you may be thinking that all you gained was the removal of the ResourceDictionary line in the XAML, but actually we’ve now opened up the BooleanToVisibilityConverter to allow it to be more like built in XAML elements.

One thing you might find with alternate BooleanToVisisbilityConverters is that they either use Visibility.Collapsed or Visibility.Hidden for false. Obviously these two Visibility values differ (collapsed allows the parent layout to use the space where a component is collapsed, hidden means the component still takes up space in the layout but is now invisible).

So it’d be nice if out BooleanToVisibilityConverter could have false assigned to either Visibility.Collapsed or Visibility.Hidden depending upon our specific requirement.

So we can change our BooleanToVisibilityConverter source to

public class BooleanToVisibilityConverter : MarkupExtension, IValueConverter
{
   public BooleanToVisibilityConverter()
   {
      WhenFalse = Visibility.Collapsed;
   }

   public BooleanToVisibilityConverter(Visibility whenFalse)
   {
      WhenFalse = whenFalse;
   }

   [ConstructorArgument("WhenFalse")]
   public Visibility WhenFalse { get; set; }

   public override object ProvideValue(IServiceProvider serviceProvider)
   {
      return this;
   }

   public object Convert(object value, Type targetType, object parameter,
                         CultureInfo culture)
   {
      bool result = (value is bool?) ?
                        ((bool?) value).GetValueOrDefault(false) :
                        false;
      if(value is bool)
      {
         result = (bool) value;
      }
      return result ? Visibility.Visible : WhenFalse;
   }

   public object ConvertBack(object value, Type targetType, object parameter,
                             CultureInfo culture)
   {
      return (value is Visibility) ?
                (Visibility) value == Visibility.Visible : false;
   }
}

As you see we’ve now added a new property, WhenFalse, and defaulted this in the constructor and ofcourse altered the return in the Convert method to return WhenFalse when the boolean is false. The ConstructorArgumentAttribute and the non-default constructor are not actually required for this to work, but are here for serialization.

In XAML we now simply declare our button as

<Button Content="Cancel" Visibility="{Binding IsCancelVisible, 
    Converter={FolderViewer:BooleanToVisibilityConverter 
    WhenFalse=Collapsed}}">