Feeds:
Posts
Comments

TypeConverters provide a means of converting a String to the appropriate .NET type or a new instance when XAML is processed. I’ve already looked at how the XAML parser searches for TypeConverters (XAML and TypeConverters ) Now let’s take a look at how to create our custom TypeConverter.

At a minimum, for a class to conform to the Silverlight implementation of TypeConverters it must be a subclass of the TypeConverter class and must contain the following two members for converting from strings for XAML processing:

1. The class must override the CanConvertFrom(…) method:

public virtual bool CanConvertFrom(
    ITypeDescriptorContext context,
    Type sourceType
)

It must return true when the sourceType parameter is String, and otherwise defer to the base implementation.

2. The class must provide an implementation of ConvertFrom(…) method:

public virtual Object ConvertFrom(
    ITypeDescriptorContext context,
    CultureInfo culture,
    Object value
)

To be usable as a TypeConverter implementation that supports XAML, this method must accept a string as the value parameter. If the string is valid, the returned object must support a cast to the type expected by the property. Otherwise it must return null.

The .NET specification for TypeConverters also contains two more key methods, which are ConvertTo and CanConvertTo. However, Silverlight 3 (as well as Silverlight 4 Beta) does not use ConvertTo and CanConvertTo, so you can skip these if your TypeConverter is for Silverlight’s XAML processing. It’s still a good idea to implement these two as a best practice for completing the wider interoperation functionality of the converter class.

 

Putting it all together: An Example:

Suppose I have a custom Silverlight control called WidgetControl, that has a property called WidgetHeight. If you need to see how to add custom controls to your project, please check out my post "Adding a Custom Silverlight Control". I use this control in my XAML file as follows:

<Custom:WidgetControl x:Name="widget" WidgetHeight="2 inches"/>

Somehow I need to handle the case where the unit of length is specified for the value of WidgetHeight property. This is done via a custom XAML TypeConverter called CustomLengthConverter, which is shown below:

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

        public override object ConvertFrom(ITypeDescriptorContext
                context, CultureInfo culture, object value)
        {

            if (value == null)
            {
                return new Double();
            }
            if (value is string)
            {
                string s = (string)value;
                if (s.Length == 0)
                {
                    return new Double();
                }

                string[] arguments = s.Split(' ');
                if (arguments.Length != 2)
                {
                    throw new ArgumentException("Value must have the format <number length_unit>");
                }
                else
                {
                    return InternalParseInput(arguments[0]);
                }
            }

            return base.ConvertFrom(context, culture, value);
        }

        public Double InternalParseInput(String inputString)
        {
            Double doubleValue;

            try
            {
                doubleValue = Double.Parse(inputString);
            }
            catch(Exception){
                doubleValue = new Double();
            }

            return doubleValue;
        }
    }

Finally, in my WidgetControl class, I explicitly specify that the WidgetHeight property should use the CustomLengthConverter defined above:

    public partial class WidgetControl : UserControl
    {
	...

        [TypeConverter(typeof(CustomLengthConverter))]
        public Double WidgetHeight
        {
	   ...
        }
    }

So every time my XAML for WidgetControl’s WidgetHeight property is parsed, the parser uses the CustomLengthConverter to convert the property value from String to the appropriate .NET type (Double)

Silverlight has a ton of controls that we can use in our Silverlight apps. Most of the times, this collection of controls is sufficient, but every once in a while, we need to create a custom control. Adding a new custom control for Silverlight is fairly straightforward, and in this blog post I am going to take a look at the steps involved in adding a new control to our Visual Studio project.

(Note: My aim is to show the steps for adding a new control, so I will not go into the specifics of the control itself)

I am going to start by creating a new project (type: Silverlight Application) in Visual Studio. Let’s call it Widget. To add a new Custom control, right click on the project in Solution Explorer, and go to Add->New Item, as shown in the figure below:

Add New Item

We get to a selection dialog which lists the various items that can be added. Let’s select “Silverlight User Control”, and change the name of the XAML file to WidgetControl.xaml

Add New Item - Selection

For this example, my new control is a pretty basic control as it simply contains a TextBox. Open the WidgetControl.xaml file, and add the TextBox element. Once done, the WidgetControl.xaml.cs file looks like:

<UserControl x:Class="Widget.WidgetControl"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400">

    <Grid x:Name="LayoutRoot" Background="White">
        <TextBox x:Name="txtBox" Text="Widget Box"></TextBox>
    </Grid>
</UserControl>

We can add new properties to our WidgetControl, and to illustrate this let’s add a new property called InternalText that is used to manipulate the text for the txtBox. Right click on the WidgetControl.xaml.cs file, and click on “View class Designer”.

View Class Diagram

When the class designer opens up right click on the WidgetControl class, click Add->Property.

Add Property

Add the new String property called InternalText. Once the property has been added, the WidgetControl.xaml.cs file will be updated automatically to include the new property. The file looks as follows:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace Widget
{
    public partial class WidgetControl : UserControl
    {
        public WidgetControl()
        {
            InitializeComponent();
        }

        public String InternalText
        {
            get
            {
                throw new System.NotImplementedException();
            }
            set
            {
            }
        }
    }
}

Since our new property simply wraps around the Text property of the TextBox, so let’s go ahead and implement our InternalText property:

        public String InternalText
        {
            get
            {
                return txtBox.Text;
            }
            set
            {
                txtBox.Text = value;
            }
        }

Using a Custom Control:

Once we’ve created a custom control, using it is pretty straightforward. All we need is to declare our xml namespace, and start using the control. Continuing my example, I’ve added my custom WidgetControl to MainPage.xaml file. The code to make this happen is on lines 6 & 11 below:

<UserControl x:Class="Widget.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:wts="clr-namespace:Widget"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400">

    <Grid x:Name="LayoutRoot" Background="White">
        <wts:WidgetControl x:Name="widgetCtrl" InternalText="Let's Text"/>
    </Grid>
</UserControl>

XAML and TypeConverters

In a XAML document, every element maps to an instance of a Silverlight (.NET) class. The properties of this instance can be set through attributes in the XAML file. There is a bit of a catch though. These attribute values (in the XAML file) are in text form, whereas the corresponding Silverlight property is a .NET type. There needs to be a way to convert these String attribute values into corresponding .NET types. This is where TypeConverters come in.

In the context of Silverlight, a TypeConverter is a class which knows how to convert between a String and a .NET type. For each attribute in XAML, the parser follows a two-step process to find the appropriate type converter:

1. The XAML parser checks the declaration of the property that corresponds to the XML attribute, and tries to see if the property contains a TypeConverter attribute. The TypeConverter attribute specifies the class that can perform the type conversion from String to the .NET type of the property. The parser then uses the TypeConverter class to convert the XML attribute into a .NET type.

2. If the property declaration does not contain a TypeConverter attribute, the XAML parser looks at the property’s Type, to see if it containts TypeConverter attribute declaration.

3. If neither the property declaration or type (class) declaration have an associated TypeConverter attribute, the XAML parser returns an error.

Let’s consider a couple of examples to better illustrate this. Suppose we have two .NET Types called a Widget and WidgetBox, which are defined as follows:

    public class Widget{
        public Brush Foreground
        {
        }
    }

    public class WidgetBox
    {
        [System.ComponentModel.TypeConverter(typeof(CustomLengthConverter)]
        public Double Height
        {
        }
    }

    public class CustomLengthConverter : System.ComponentModel.TypeConverter
    {
        ...
    }

Example-1:

Consider the following XML element in the XAML file.

	<WidgetBox Height="1in" />

1. When the XAML parser encounters this code, it checks the property declaration for Height. In this case, it finds a TypeConverter attribute for the Height property, which tells the parser to use the CustomLengthConverter class to convert the string "1in" to Double. So, this snippet of XAML code is equivalent to:

	WidgetBox wb = new WidgetBox();
	wb.Height = new CustomLengthConverter().ConvertFrom("1in");

Example-2:

Here’s another snippet of XAML code:

	<Widget Foreground="Blue" />

1. When XAML parser encounters this code, it first checks the property declaration for Foreground. There’s no TypeConverter associated with the Foreground property, so the parser moves to step-2.

2. Now the XAML parser checks the class declaration of the Foreground’s Type. In our example, the type of Foreground is Brush, and it turns out that the Brush class is decorated with the [TypeConverter(typeof(BrushConverter))] attribute declaration:

	[TypeConverter(typeof(BrushConverter))]
	public class Brush
	{
	...
	}

In this case, the parser uses the BrushConverter class to convert the string "Blue" into a Brush .NET type. So this snippet of XAML is equivalent to:

	Widget w = new Widget();
	w.Foreground = new BrushConverter().ConvertFrom(&quot;Blue&quot;);

For more information about TypeConverters, check out MSDN. There’s also a lot of great information at Rob Relyea’s blog post about TypeConverters

XAML stands for eXtensible Application Markup Language (pronounced zamm-uhl). It is an XML based markup language used to instantiate .NET objects. XAML was initially designed as part of Windows Presentation Foundation (WPF), and allows developers to define rich user interfaces. A XAML file defines the elements that make up a content region. This enables a clean separation between UI and the business logic code. One big advantage of this separation is that the UI designers can focus on creating the user-interface in XAML (using tools such as Microsoft’s Expression), and the developers can then create the business objects corresponding to the UI.

XAML document has the following properties:

- Every element in a XAML documents maps to an instance of a Silverlight (.NET) class, and its name exactly matches that of the class.
- The properties of each class can be set through attributes in the XAML file.
- Similar to any XML document, a XAML element can contain nested elements.

For example, when we create a new Silverlight application (called SampleApplication) in Visual Studio 2010 (beta), we get the following skeleton XAML document:

<UserControl x:Class="SampleApplication.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400">

    <Grid x:Name="LayoutRoot" Background="White">

    </Grid>
</UserControl>

As I’ve mentioned before, XAML allows us to create user-interfaces. However, for the interface to be useful, it needs to connect to code (typically written in C#). To accomplish this, we need a way to connect the event handlers with the UI. Usually, every XAML file has a corresponding class with client-side C# code. This class is generated by the Class attribute in the XAML namespace. This attribute tells the Silverlight parser to create a new class with the specified name that derives from the class represented by the XML element. When the XAML code above is parsed, the parser creates a new class named SampleApplication.MainPage, which derives from the UserControl class. This class is in the file called MainPage.xaml.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace SampleApplication
{
    public partial class MainPage : UserControl
    {
        public MainPage()
        {
            InitializeComponent();
        }

    }
}

The class is partial , as it is split across two files. The code that we write goes into MainPage.xaml.cs. The rest of the class definition contains auto-generated code and goes into a file called MainPage.g.cs. In the solution, this file is located in obj\Debug folder. For the above XAML code, the contents of this auto-generated file are as follows:

using System;
using System.Windows;
using System.Windows.Automation;
using System.Windows.Automation.Peers;
using System.Windows.Automation.Provider;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Markup;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Imaging;
using System.Windows.Resources;
using System.Windows.Shapes;
using System.Windows.Threading;

namespace SampleApplication {

    public partial class MainPage : System.Windows.Controls.UserControl {

        internal System.Windows.Controls.Grid LayoutRoot;

        private bool _contentLoaded;

        /// <summary>
        /// InitializeComponent
        /// </summary>
        [System.Diagnostics.DebuggerNonUserCodeAttribute()]
        public void InitializeComponent() {
            if (_contentLoaded) {
                return;
            }
            _contentLoaded = true;
            System.Windows.Application.LoadComponent(this, new System.Uri("/SampleApplication;component/MainPage.xaml", System.UriKind.Relative));
            this.LayoutRoot = ((System.Windows.Controls.Grid)(this.FindName("LayoutRoot")));
        }
    }
}

Finally, a quick note about the Name attribute. If we want to access and manipulate Silverlight elements programmatically, XAML must include the Name attribute. This is useful if we want to change properties or attach and detach event handlers on the fly. In the above example, line-9 of the XAML file tells the XAML parser to add the following field to the autogenerated portion of the MainPage class

private System.Windows.Controls.Grid LayoutRoot;

Recently, I had to use STL Port for a particular project. While debugging, I was hampered by the fact that my data structures were not providing as much information in the watch window as I would have hoped. Using std::vector as an example, here’s a screen shot that highlights the problem.

Screentshot before modifications to autoexp.bat file

Screentshot before modifications to autoexp.bat file

After a bit of investigation I disovered the wonderful autoexp.dat file for Visual Studio. Visual studio 2005 and 2008 allow you to customize native variable watch: i.e. how a variable previews in the watch window and tooltips. This is done via a file called autoexp.dat (auto-expand), which is hidden deep inside the VS installation (%VS_INSTALL_DIR%\Common7\Packages\Debugger). Official documentation on the specifics of the scripting language is sparse, and Microsoft’s MSDN article contains the disclaimer “The structure of this file and syntax of autoexp rules might change from one release of visual studio to the next”.

For most part, the instructions on how to write auto-expand rules for native types are located in the file itself. There are some other resources that are great to get started

Anyway, back to my predicament. After some research and some trial and error, the following visualizer worked for STLPort’s std::vector.

;———————————————–
;  STLPORT visualizer
;———————————————–

;———————————————–

;  stlp_std::vector
;———————————————–
stlp_std::vector<*>{
children
(
#array
(
expr :    ($c._M_start)[$i],

size :    $c._M_finish-$c._M_start
)
)
preview
(
#(
“[",
$e._M_finish - $e._M_start ,
"](“,

#array
(
expr :     ($c._M_start)[$i],
size :     $c._M_finish-$c._M_start
),
“)”
)

)
}

I copied the above block in the autoexp.dat file of my Visual Studio installation, and tried to look at the data structures again. I discovered that I had to make a slight modification to the above visualiser for it to work properly in the debug mode. STLPort uses debug versions of data structures in debug builds, and as a result I had to rename stlp_std::vector to stlpd_std::vector for things to work as expected. Here’s the visualiser for debug builds, followed by the screenshot of how things acually look in the watch window.

;———————————————–

;  stlpd_std::vector
;———————————————–
stlpd_std::vector<*>{
children
(
#array
(
expr :    ($c._M_start)[$i],

size :    $c._M_finish-$c._M_start
)
)
preview
(
#(
“[",
$e._M_finish - $e._M_start ,
"](“,

#array
(
expr :     ($c._M_start)[$i],
size :     $c._M_finish-$c._M_start
),
“)”
)

)
}

Screentshot after modifications to autoexp.bat file

Screentshot after modifications to autoexp.bat file

The resources linked above should be a great place if you want to experiment with autoexp.dat file.

I must point out that there is a potentially better way to create visualizers for custom types. MSDN has a couple of good articles to get you started, particularly Visualizers and How to: Write a Visualizer

Java Enum Puzzler

Recently, I ran into an interesting bit of code related to Java enumerations. Here’s a contrived minimal sample:

/*
 * Some arbitrary resource type
 */
interface Resource {
	public Resource getResource();
}

enum A implements Resource{
	ALPHA (B.BRAVO);

	private Resource res;
	private A (Resource res){ this.res = res; }
	public Resource getResource(){ return res; }
}

enum B implements Resource{
	BRAVO (C.CHARLIE);

	private Resource res;
	private B (Resource res){ this.res = res; }
	public Resource getResource(){ return res; }

}

enum C implements Resource{
	CHARLIE (A.ALPHA);

	private Resource res;
	private C (Resource res){ this.res = res; }
	public Resource getResource(){ return res; }
}

class EnumTester{
	public static void main(String [] args){
		System.out.println(A.ALPHA.getResource());
		System.out.println(B.BRAVO.getResource());
		System.out.println(C.CHARLIE.getResource());
	}
}

When this code is run, an intuitive expectation is to see the following printed to the console:

BRAVO
CHARLIE
ALPHA

However, when I actually run the code we see:

BRAVO
CHARLIE
null

While this may seem a bit funky, the key is to understand what enum constants mean in Java. The key question to address is: “when is the constructor for an enumerated type invoked”. To answer this, it is helpful to remember that enum constants are implicitly public static final. Java guarantees that:

  • Static variables in a class are initialized before any object of that class can be created
  • Static variables in a class are initialized before any static method of the class runs

Knowing this, the behavior of the above code snippet becomes clearer. Here’s what happens in the main method:

  1. The fun happens at line 35, when we print   A.ALPHA.getResource(). Behind the scene, the class loader loads enumeration A into memory (i.e. initializes A).
  2. Once A is loaded into memory, the enum constant ALPHA gets created via call to the constructor where B.BRAVO is passed in as the argument.
  3. At this point, enumeration B is initialized and enum constant BRAVO gets created via a call to the constructor where C.CHARLIE is passed in as the argument.
  4. Same as before, now enumeration C is initialized (i.e. loaded into memory). Now here’s where things become interesting.
  5. Immediately after the initialization of C, we create the enum constant CHARLIE via a call to the constructor and pass in A.ALPHA as the argument. However, A.ALPHA has not been instantiated yet, and therefore enum constant CHARLIE gets null as the value of its resource instance variable. 

This means that once the statement A.ALPHA.getResource() is evaluated, A, B and C are all loaded into memory and all the corresponding enum constants have already been instantiated. Lines 35-37 simply then print the corresponding resources for each enum constant.

A Possible Solution

It is obvious that the entire problem stems from the cyclic dependency between A, B and C. Usually (but not always), this is an indication of a bad design choice and the fix is to simply get rid of the cyclic dependency. Assuming we want to keep the dependency, what are our options then?

Our solutions lies in Java’s ability to allow instance-specific methods on enumerations. This is shown in the code below.

Running the following code with the EnumTester main method above will give us the results we wanted, without the problems caused by the previous approach.

enum A implements Resource{
	ALPHA { public Resource getResource() {return B.BRAVO; } };

	public abstract Resource getResource();
}

enum B implements Resource{
	BRAVO { public Resource getResource() { return C.CHARLIE; } };

	public abstract Resource getResource();
}

enum C implements Resource{
	CHARLIE { public Resource getResource() { return A.ALPHA; }};

	public abstract Resource getResource();
}

What do you think? Do you know of any other ways to resolve the cyclic dependency? Have you seen any other weirdness related to Java’s Enums?

Apparently, wordpress.com does not play nicely with pasting source code, especially if you are using the excellent Windows Live Writer and its Code Snippet plugin. I had to google quite a bit before I could figure out the right way to paste source code to my blog using WLW. Thanks to Vadim for his very useful post.

So here’s my test to see if I can post source code properly:

public class HelloWorld {
	public static void main(String [] args){
		System.out.println("Hello, WordPress.com");
	}
}

Hello world!

This blog is my attempt at trying to become a better programmer, or put another way, an attempt to suck less. I love programming and love learning new stuff, so this blog will hopefully contain my notes and thoughts as I explore new languages and technologies and will act as my programming journal.

Occasionally, I might end up writing about technology in general or meta-programming. Depending on time, I also hope to track the evolution of my personal programming projects via this blog.

I would love to hear your thoughts whether you agree or disagree, as it would be fantastic to get different perspectives. So please feel free to leave comments.

Finally, all views expressed on this blog are my own and in no way represent the views of my employer (had to be said :-) )