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.

Feb 26 2010

Enable Silverlight 4 Tools in Visual Studio 2010 Release Candidate

Are you still waiting for Microsoft to release Silverlight 4 for Visual Studio 2010 RC?

I'm not anymore :)

You could completely use Silverlight 4 bits for VS 2010 Beta 2 with VS 2010 RC. Alex Sorokoletov has found how to install Silverlight 4 on VS 2010 RC.

There is no magic and steps are simple as One, Two, Tree:

  1. Download Silverlight 4 Tools For VS 2010 Beta 2
  2. Run installation. The dialog window saying what Visual Studio 2010 Beta 2 should be installed will appear. Don’t hit the cancel button!
  3. Locate folder named like ‘bfb0032a835647b79718f26ba81d3392’ on root of some of your hard drives. And copy it’s content to some other location.
  4. Open ParameterInfo.xml and comment out <BlockIf DisplayText="Visual Studio 2010 Beta 2 ..."> section (it is placed on lines 13-41)
  5. Now you are ready to SPInstaller.exe to install Silverlight 4 Tools
  6. One additional step is required to force Visual Studio to use Silverlight 4 instead of Silverlight 3 for visual designers. To do it open regedit and search for DesignerPlatforms. Under this key go to Silverlight and change SilverlightHost value to ‘4.0’.

You should be happy now :)

If you need RIA services then load patched Microsoft.RiaServices.Tools.dll assembly and copy it to ‘c:\Program Files\Microsoft SDKs\RIA Services\v1.0\Libraries\Server’ folder.

And then open GAC management console by [Win+R] -> assembly ->[Enter]. Remove old one assembly and add new one.

Restart Visual Studio and you are done.

Thanks for Alex!

Feb 03 2010

Can’t attach Silverlight debugger when System.Windows.Browser.HtmlPage.Window.Navigate is used to open new window

If you can’t attach the debugger to a Silverlight application opened in new browser window using HtmlPage.Window.Navigate method then do the following:

  1. Go to Debug –> Attach to Process
  2. In Attach to Process dialog select process which host Silverlight application
  3. Click on “Select…” button under “Attach to:” section
  4. In Select Code Type window select “Debug this code type” option and uncheck all checkboxes except Silverlight
  5. Click OK –> Attach