Apr 15 2011

Silverlight 4 Binding debug

Hi all,

Microsoft released Silverlight 5 first beta (you can download it from here).

Unfortunately it has not so many futures as we probably expected to get in this first drop of Silverlight 5.

This build of the Silverlight 5 includes next top futures:

  • XAML Debugging with breakpoints for binding debugging
  • Implicit data templates for easy UI reuse
  • Double (and multi) click support
  • GPU-accelerated XNA-compatible 3D and immediate-mode 2D API
  • Low-latency sound effects and WAV support
  • Real operating system windows and multi-display support
  • Significant performance improvements, fixes and much more

 

Most of these futures could be used only in Silverlight 5 applications, but not the first one :)

But it's amazing that by installing Silverlight 5 tools for Visual Studio we can get XAML Debugging (Binding Debugging) not only for Silverlight 5 applications but also for Silverlight 4 applications!

Let's try it:

The goal is to build Silverlight 4 based application and try Binding Debugging in it. After we make sure that binding debugging work correctly we will try to run our application on PC which has only Silverlight 4 installed.

 

1. Create Silverlight 4 application

Let's create Silverlight 4 based application first. Select Silverlight 4 in Silverlight Version combobox:

2. Test Binding Debug

Now let's create some class to which we will bind to and set DataContext of our form:

In xaml we will use simple <Textblock /> to display text stored in SomeString property of the Data class.

Ok, now we all set to start testing Binding Debug.

Place a caret inside binding element and hit F9 to set a break point.

Now start application and see that debugger is able to stop on break point and you could see binding details in Locals window:

 

Ok, so we are able to use Binding Debugging even with Silverlight 4 applications.

Update: you still can debug Binding in XAML even if your application is built using Silverlight 4 tools only! Try to lunch any application which you have built before installing Silverlight 5 tools and see that you can place a break point in XAML and debugger can stop on that break point and show binding details for you :)

Apr 13 2011

Silverlight 5 beta - download link

Hi all,

 

We all are waiting for Silverlight 5 beta which should be released today.

Good news: Microsoft created a page with Silverlight 5 download link.

Bad news: it still points to the Silverlight 4 installer :(

 

But it's almost here ;)

Jun 08 2010

Initialization State Manager

Often you need to run some initialization operations during application startup or control creation. Assume you can’t show or enable UI till all operations complete. In this case you need some code to watch for server requests and raise some ‘InitializationCompleted’ event when all requests are done.

This piece of code should store and manage current state (which operations are in Running state and which one are completed) somehow. And it is better if state management code will be reusable.

This is exactly what I gonna  to build for you.

I’d like the idea to use enum to define initialization phases:

[Flags]
public enum InitializationPhases: uint
{
	None = 0,
	MachineSeetingsLoad = 1,
	UserSettingsLoad = 2
}

Please note that I use Flags attribute on the enum type. This allow us to use bitwise operations on enum values.

The idea is to set particular bit to ‘1’ when operation starts and mark as ‘0’ when operation completes. If all bits become ‘0’ then all operations will be completed.

To make code reusable I’d like to create generic type. Unfortunately we can’t  define enum constraint for generic type parameter. But enum is also a structure so at least we could constraint generic parameter to structures.

Enum type support IConvertable interface. Which allow us to perform conversion to uint value and then we could do bitwise operations with that value. The only moment we should be sure about is that generic type is created with enum generic parameter. To check it we will use .NET  reflection.

public class InitializationStateManager<T> : INotifyPropertyChanged
    where T : struct, IConvertible
{
    private UInt32 _initializationPhasesInRun;

    static InitializationStateManager()
    {
        Type t = typeof(T);

        if (!t.IsEnum) throw new ArgumentException("T must be an enumerable type");

        bool flagsAttributeFound = false;
        foreach (object attribute in t.GetCustomAttributes(false))
        {
            flagsAttributeFound = attribute is FlagsAttribute;
            if (flagsAttributeFound) break;
        }
        if (!flagsAttributeFound) throw new ArgumentException("T must be marked with Flags attribute");
    }

    public bool IsInitialized
    {
        get { return _initializationPhasesInRun == 0; }
    }

    #region INotifyPropertyChanged Members

    public event PropertyChangedEventHandler PropertyChanged;

    #endregion

    protected void OnPropertyChaneged(String propertyName)
    {
        if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }

    public void MarkPhaseCompleted(T phase)
    {
        _initializationPhasesInRun &= ~phase.ToUInt32(null);
        OnPropertyChaneged("IsInitialized");
    }

    public void MarkPhaseStarted(T phase)
    {
        _initializationPhasesInRun |= phase.ToUInt32(null);
    }
}

In constructor we check what generic type parameter is enum and marked with Flags attribute.

Two methods MarkPhaseStarted and MarkPhaseCompleted are used to indicate that initialization phase started or completed. When all initialization phases will be completed the PropertyChanged event will be raised.

There are still some missed functionality:

  1. Code is not thread safe
  2. Probably it should be a Start() method to indicate that all initialization phases are started, to avoid the situation when some phase will complete before other one start
Mar 05 2010

Binding a Converter Parameter

There are a lot of situations when you need to bind ConverterParameter value.

Imagine that you have Receipt class with two fields: amount and currency type. And you need to format amount string to something like $1,000.00 or ¥1,000.00 depending on currency type. So the good idea is to use converter to do formatting.

The good way is to have something like AmountFormatter which takes amount and currency type and does the formatting.

Current version of the Silverlight disallowing us to bind Converter Parameter value.  But we could pass whole Reciept object to the formatter and take amount and currency type from it directly. Such formatter could look like this:

public class AmountConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var receipt = value as Receipt;
        if (receipt != null)
        {
            return String.Format("{1}{0:0,0.0}", receipt.Amount, receipt.CurrencyChar);
        }
		return value.ToString();
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        ...
    }
}

This method is not good cause we tide converter and particular class (in our case it is Receipt). But what could we do?

Ok, we want to have a reusable converter. But we need to pass several values to it at the same time. Then lets simply define an interface which converter is expecting to get:

 

public class AmountConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var data = value as IConverterData
        if (data != null)
        {
            return String.Format("{1}{0:0,0.0}", data.Value, data.CurrencySign);
        }
		return value.ToString();
    }

	... 

	public interface IConverterData
    {
        string Value { get; set; }
        string CurrencySign { get; set; }
    }
}

Now to prepare Receipt class to be used in conjunction with AmountConverter we just need to implement AmountConverter.IConverterData interface.

And the usage will look like this:

<TextBlock Text="{Binding Converter={StaticResource AmountConverter}}"/>

Please not what we binds to the whole object here.