Speaking at Milwaukee Area Silverlight SIG

by Damon Payne 5. June 2011 19:03

Long ago, when Silverlight 2 was new, we had a Silverlight User Group in Milwaukee.

Tuesday, June 7th we are re-launching the Milwaukee Silverlight Special Interested Group.  I will be presenting on the topic "What's new in Silverlight 5".  I would highly suggest attending this meeting if you are a Silverlight or Windows Phone 7 developer or at all interested in these topics.  We will be looking to talk to local developers about what Silverlight topics interest them and will also be recruiting presenters for future meetings.

A location map and registration can be found here:  http://www.wi-ineta.org/DesktopDefault.aspx?tabid=192 .  I hope to see you there!

Tags:

Silverlight | Technical Community | Windows Phone 7 Development | WindowsPhone7

Using ICustomTypeProvider in Silverlight 5

by Damon Payne 14. April 2011 13:55

Why would I want to trick Silverlight into treating Dictionary values like real Properties?
There are scenarios when complex, data-intensive applications will need to data bind to keys/value pairs or generally determine the properties of a Class at runtime.  In cases where there could be large numbers of keys or the keys could change without an application re-deploy, this is a tricky problem to solve.  I wrote about using Reflection Emit for two-way data binding to dictionaries quite a while ago.

In Silverlight 5, however, you can use ICustomTypeProvider to achieve the same goal in a clean fashion.

Data Facets

Some systems, such as Pivot Viewer, allow you to specify any number of pseudo-Properties about interesting items, which we’ll call Facets.  Using a structure like a Dictionary, we could specify any number of Facets.  Two-way data binding to these is problematic however since they aren’t real CLR properties.  In the full .NET Framework you can do tricks with ICustomTypeDescriptor, and now in Silverlight 5 we have System.Reflection.ICustomTypeProvider.
Let’s create a simple Facet class to represent data about the Facet we’d like to data bind to.

/// <summary>
/// Some facet of a dynamic type
/// </summary>
public class Facet
{
    /// <summary>
    /// Must be a valid CLR property name
    /// </summary>
    public string PropertyName { get; set; }

    public Type PropertyType { get; set; }

    //Couple of demo Facets

    public static Facet DynamicDemo0 = new Facet
    {
        PropertyName = "DynamicPropZero",
        PropertyType = typeof(string)
    };

    public static Facet DynamicDemo1 = new Facet
    {
        PropertyName = "DynamicPropOne",
        PropertyType = typeof(double)
    };
}

Next we’ll create an object with a regular CLR property and a dictionary to store key/value pairs.  These key value pairs will be made binding-friendly.

/// <summary>
/// An Class with normal properties, but also supporting dynamic properties
/// </summary>
public class FacetedObject : ICustomTypeProvider, INotifyPropertyChanged, INotifyDataErrorInfo
{
    Dictionary<string, object> _facetValues;

    public object this[string key]
    {
        get
        {
            if (!_facetValues.ContainsKey(key))
            {
                return null;
            }
            return _facetValues[key];
        }
        set
        {
            _facetValues[key] = value;
            OnPropertyChanged(key);
        }
    }

The interesting thing here is the ICustomTypeProvider interface implementation. 

ICustomTypeProvider Implementation

On any CLR object you can call GetType().  If you’ve ever done any reflection programming you’re aware of all the rich runtime metadata about your classes that System.Type can provide.  System.Type is also an abstract class, and ICustomTypeProvider requires only a single method implementation:

public Type GetCustomType()
{
    return new FacetedObjectType<FacetedObject>(_currentFacets);
}

So, we can create a class that extends System.Type and do some interesting things.  We can trick the Silverlight runtime into thinking our Facets are real CLR Properties.  While my FacetObjectType<TSource> implementation is about 300 lines long, here’s the most interesting part:

/// <summary>
/// A custom System.Type implementation that can provide different Properties at runtime. 
 All operations except those related to
/// Property logic delegated to the type of TSource
/// </summary>
/// <typeparam name="TSource"></typeparam>
public class FacetedObjectType<TSource> : System.Type
{
//snip…


    public override System.Reflection.PropertyInfo[] GetProperties(BindingFlags bindingAttr)
    {
        var properties = ProxyTargetType.GetProperties(bindingAttr);

        if (
           BindingFlags.Instance == (bindingAttr & BindingFlags.Instance)
        && BindingFlags.Public == (bindingAttr & BindingFlags.Public)
        )
        {
            var dynamicProperties = GetPublicDynamicProperties();
            var allprops = new List<PropertyInfo>();
            allprops.AddRange(properties);
            allprops.AddRange(dynamicProperties);
            return allprops.ToArray();
        }
        return properties;
    }
//snip…

So, for system types that implement ICustomTypeProvider, we can intercept important requests for reflection information and supplement that information.  In our case here, we can claim that properties exist that aren’t really on our class at compile time.  In terms of telling the runtime how to actually Get and Set these dynamic properties, we need to create a class that extends PropertyInfo.  Here’s a type called DynamicPropertyInfo, and the two most interesting methods:

public class DynamicPropertyInfo : PropertyInfo
{
    public DynamicPropertyInfo(Type propertyType, Type declaringType, string propertyName)
    {
        _propertyType = propertyType;
        _declaringType = declaringType;
        _name = propertyName;
    }

    public override object GetValue(object obj, BindingFlags invokeAttr, Binder binder,
        object[] index, System.Globalization.CultureInfo culture)
    {
        var fo = obj as FacetedObject;
        return fo[Name];
    }

    public override void SetValue(object obj, object value, BindingFlags invokeAttr, Binder binder,
        object[] index, System.Globalization.CultureInfo culture)
    {
        var fo = obj as FacetedObject;
        fo[Name] = value;
    }

In here, we can just use the this[] indexer of our FacetedObject class to get and set values.

NoteI’m only showing basic custom properties here, but there’s a lot more you can do with ICustomTypeProvider.  Most of the methods in FacetObject<TSource> and DynamicPropertyInfo just delegate to the original Type.  I’d love comments/email on specific scenarios you’re interested in.

Demo App

To show how this concept works, let’s create a Silverlight 5 application with a DataGrid.  We’re going to get the datagrid to display “properties” that technically speaking are not there.  First we’ll create a couple of Facets assigned to FacetedObject by default called “DynamicPropZero” and “DynamicPropOne”.  For these two we can create DataGridColumns along with an actual compile-time Property of FacetedObject.

            <sdk:DataGrid.Columns>
                <sdk:DataGridTextColumn Header="Id" IsReadOnly="True" Binding="{Binding Id}" />
                <sdk:DataGridTemplateColumn Header="Dynamic Property 0">
                    <sdk:DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <TextBox Text="{Binding DynamicPropZero, Mode=TwoWay, 
                                NotifyOnValidationError=True,
                                ValidatesOnNotifyDataErrors=True,
                                ValidatesOnDataErrors=True,ValidatesOnExceptions=True}"/>
                        </DataTemplate>
                    </sdk:DataGridTemplateColumn.CellTemplate>
                </sdk:DataGridTemplateColumn>
                <sdk:DataGridTextColumn Header="Dynamic Property 1"
                                        Binding="{Binding DynamicPropOne, Mode=TwoWay}" />
            </sdk:DataGrid.Columns>

Here’s the code we’re using to create the sample data in our main ViewModel.  Note that we're going to explose the dictionary values as properties.

public class ShellViewModel : INotifyPropertyChanged
{
    public ShellViewModel()
    {
        Items = new ObservableCollection<FacetedObject>();
        var d0 = new FacetedObject();
        d0[Facet.DynamicDemo0.PropertyName] = "I'm a property!";
        d0[Facet.DynamicDemo1.PropertyName] = 42.42;

        var d1 = new FacetedObject();
        d1[Facet.DynamicDemo0.PropertyName] = "Would you like to be a property too?";
        Items.Add(d0);
        Items.Add(d1);

And as you can see, it works:

BindingApp0

Notice the buttons above the DataGrid.  These dynamic properties wouldn’t be very useful unless they are first-class citizens, and they are.  Note that FacetedObject also implements INotifyPropertyChanged and INotifyDataErrorInfo.  By clicking the buttons we fire commands that affect changes in code, and the UI reflects the changes for the dynamic properties.

BindingApp1

Now, recall at the beginning that I said this could be completely dynamic and that we could actually create both the Facet data and visuals in a data driven fashion at runtime.  Clicking on the Add Facet button demonstrates this.

BindingApp2

After clicking OK, we can do some work to add this Fact to the items on the ViewModel, and also dynamically create a new DataGridColumn to display the data.

public void AddNewFacet(string name, object defaultValue, string clrType)
{
    var typeDict = new Dictionary<string, Type>();
    typeDict["string"] = typeof(string);
    typeDict["int"] = typeof(int);
    typeDict["double"] = typeof(double);

    //1. Create a new Facet
    var newFacet = new Facet
    {
        PropertyName = name,
        PropertyType = typeDict[clrType]
    };

    //2. Tell objects to clear out cached state
    //3. Assign a default value we can see in the UI
    var vm = DataContext as ShellViewModel;
    
    foreach (var item in vm.Items)
    {
        item.AddFacet(newFacet);
        item[newFacet.PropertyName] = defaultValue;
    }

    //4. create visuals to bind to new facet
    var sb = new StringBuilder("<DataTemplate 
xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\" >")
    .Append("<TextBox Text=\"{Binding  ")
    .Append(name)
    .Append(", Mode=TwoWay}\" />")
    .Append("</DataTemplate>");

    var dt = (DataTemplate)XamlReader.Load(sb.ToString());
    var column = new DataGridTemplateColumn();
    column.Header = name;
    column.CellTemplate = dt;
    FacetGrid.Columns.Add(column);
}

Our new DynamicProperty is now shown in the DataGrid and we can edit it with two-way binding support:

BindingApp3

For some, this last piece of code will look like the worst kind of voodoo, but there are cases where your requirements will dictate this level of flexibility and this combination of techniques will help you get there.

Conclusion

You can see a lot of other places you could take this.  Download the source code and you’ll see some comments.  For one example, you could easily extend this sample to add System.ComponentModel.DataAnnotations attributes to your properties to have automatic validation from the Controls that support it.  This method is much cleaner than the reflection Emit route and gets away from some of the issues that route can cause.
It’s always been easy to accomplish extreme feats of dynamism in XAML by using XamlReader but ICustomTypeProvider brings a new level of runtime fun to your data types.

Demo Solution Source:

DamonPayne.CustomFacetBinding.zip (646.97 kb)

Tags:

Architecture and Design | Silverlight

Another Journey of Learning and Teaching is Coming

by Damon Payne 1. April 2011 21:15

Back in September of 2008 during the Silverlight 2 era I wanted to do a proof of concept for a Silverlight design surface.  I called this Argentum Tela.  My goal was to take a complex project and blog about the various design decisions that were made, why they were made, and to just have fun.  The project started here on my blog and ended here on codeplex.  I still get a lot of questions about this project and I've had some people use it in commercial business apps.

I don't have all the answers, I'm a fellow traveler on this road; however I have been doing a lot of complex Silverlight applications for more than three years now and along the way I've formed some patterns and practices.  For the next couple of months I'll be sharing that knowledge with you.

Tags:

Architecture and Design | Silverlight

Delay Binding Updates within a certain Context

by Damon Payne 16. March 2011 14:16

This came up on Twitter today and since I have a solution that's been working well for me I opted to share. When making a series of data changes that will update Bindings, How can you keep a WPF/Silverlight UI from reflecting any of these changes until you're all done?  In other words, we need the ability to treat a series of Property changes as a single unit of work.

While this works better with the design patterns from my series "Great Features for MVVM Friendly Objects" I will define a more general mechanism here.

Step 1 - Define a mechanism for not firing PropertyChanged

The first step is to give your data objects a means of not firing updates.  We'll create a simple base class here to demonstrate the principles.

public class SampleDataObject : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        /// <summary>
        /// Don't fire updates!
        /// </summary>
        public bool SuspendChangeNotification { get; set; }

        protected void OnPropertyChanged(string propName)
        {
            if (null != PropertyChanged && !SuspendChangeNotification)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propName));
            }
        }
    }

 

Step 2 - Define Reasonable Programming Semantics for Context Boundaries

Whenever I'm solving a problem I always think about the Developer Experience.  Is this going to be so annoying or hard to use that people will seek reasons to avoid using it?  Since we want to define a context with a clear beginning and end I like to see if the problem can be expressed with using() semantics.  It turns out that this one can be.  We'll create an object that does the work we need to do and implements IDisposable so it can be used in a using() {} block:

public class SuspendChangeNotifyContext: IDisposable
    {
        public SuspendChangeNotifyContext(ISupportInitialize target) : this(new List<ISupportInitialize>{target})
        {
        }

        public SuspendChangeNotifyContext(IEnumerable<ISupportInitialize> targets)
        {
            _targets = targets;
            foreach (var t in _targets)
            {
                t.BeginInit();
            }
        }

        IEnumerable<ISupportInitialize> _targets;

        public void Dispose()
        {
            foreach (var t in _targets)
            {
                t.EndInit();
            }
        }
    }

 

This means that our SampleDataObject needs to implement ISupportInitialize, which causes us to implement methods for BeginInit() and EndInit().  I chose this because this interface is already in the Silverlight libraries.  You could certainly make your own interface that looks directly at some other property or methods.

    public class SampleDataObject : INotifyPropertyChangedISupportInitialize
    {
        public event PropertyChangedEventHandler PropertyChanged;
 
        /// <summary>
        /// Don't fire updates!
        /// </summary>
        public bool SuspendChangeNotification { getset; }
 
        protected void OnPropertyChanged(string propName)
        {
            if (null != PropertyChanged && !SuspendChangeNotification)
            {
                PropertyChanged(thisnew PropertyChangedEventArgs(propName));
            }
        }
 
        public void BeginInit()
        {
            SuspendChangeNotification = true;
        }
 
        public void EndInit()
        {
            SuspendChangeNotification = false;
        }
    }

 

Now that we have all of this, we can write reasonable looking code like the following:

            var dataObject = new SampleDataObject();
            using (var ctx = new SuspendChangeNotifyContext(new List<ISupportInitialize> { dataObject }))
            {
                //make Property changes here!
            }

That's an extremely reasonable looking way to accomplish our goal, but we're not quite done yet.

Step 3 - Done Making Changes

Of course, what's missing from the above example is that after we're done, we want to notify the UI all at once about the changes we made during the SuspendChangeNotify batch.  Given what we already have that is extremely easy to do.  We can keep track of which properties changed and fire Notification for them all from EndInit().

    public class SampleDataObject : INotifyPropertyChangedISupportInitialize
    {
        public event PropertyChangedEventHandler PropertyChanged;
 
        List<string> _batchChanges;
 
        /// <summary>
        /// Don't fire updates!
        /// </summary>
        public bool SuspendChangeNotification { getset; }
 
        protected void OnPropertyChanged(string propName)
        {
            if (SuspendChangeNotification)
            {
                if (!_batchChanges.Contains(propName))
                {
                    _batchChanges.Add(propName);
                }
            }
            else if (null != PropertyChanged)
            {
                PropertyChanged(thisnew PropertyChangedEventArgs(propName));
            }
        }
 
        public void BeginInit()
        {
            SuspendChangeNotification = true;
            _batchChanges = new List<string>();
        }
 
        public void EndInit()
        {
            SuspendChangeNotification = false;
            foreach (string propName in _batchChanges)
            {
                OnPropertyChanged(propName);
            }
            _batchChanges = null;
        }
    }

Because we've done this with using() blocks this is a fairly safe way to accomplish this without concerns that the data objects will get "wedged" if an exception is thrown.

A Final Note on Design

The approach shown here, works but might appear a little untidy.  If you check out my (ongoing) series on Great Features for MVVM Friendly Objects you can see a means of an elegant repackaging of what's shown here.  This is especially true of the change-tracking portion of the code.

Enjoy!

Tags:

Architecture and Design | Silverlight | WPF

MEF for Windows Phone 7

by Damon Payne 1. March 2011 17:45

I wrote a while back about my port of MEF to Windows Phone 7, and apprently didn't make a binary available as I've been getting email and twitter requests for it.

Download it here.

See the original article for detailed notes.  The big points are that dynamic export metadata won't work due to not having Reflection Emit on WP7 and that DeploymentCatalog doesn't really make sense so I excluded System.ComponentModel.Composition.Initialization -  use AssemblyCatalogs instead.

I will be maintaining this so please report any issues.

Why is this not part of MEF Contrib?  Mostly due to some timing issues last year and my own GitHub issues.

Tags:

Silverlight | Windows Phone 7 Development | WindowsPhone7 | MEF

Edgenet Partners with Search Giant Bing

by Damon Payne 16. February 2011 15:48

Another press release for last year's big project!

http://www.edgenet.com/index.php/bing-webinar/bing-webinar.html

"We're proud to announce a new partnership with the search giant Bing. Bing highly values the quality and features of the data we provide, and we welcome their partnership as we continue to enhance your web presence."

Check it out.

Tags:

Silverlight | Technical Community

Upcoming Speaking Engagements

by Damon Payne 13. February 2011 19:38

Well, I didn’t get to speak at MIX 2011 as neither of my Open Call submissions got enough votes.  However, there are some most excellent closer-to-home venues I’ll be presenting at in the not to distant future:

Deeper in .NET 2011

http://www.wi-ineta.org/DesktopDefault.aspx?tabid=203

Well, it’s been a couple of years, but Milwaukee is going to have an awesome code camp again. This is going to be an awesome event with Mads Kristensen, Jay Schmelzer, Joe Stagner, Rocky Lhotka and.. me!  (Me?)How I get to take the stage next to giants like these guys remains a mystery but I have to thank the organizers for making room for a home-town presenter. 

 

Fox Valley Day of .NET

http://dayofdotnet.fvnug.org/

I think this will be my third year in a row speaking at this event.  Wow am I getting old.  The guys in the Fox Valley have really created a fantastic community up there.  The Fox Valley guys are cutting edge, busy, and bigger than most people down in the Metro Milwaukee area realize.  Not only is this a great event every year but they take great care of the speakers.  <Beer/>  I'm definitely looking forward to this event. 

It’s too bad that, at this event, I’m going to have to make some tough decisions.  My compatriots from the Madison area, Lance Larsen and Travis Feirtag, are both giving great talks at the same time.  I can’t see Scott Seely’s talk because he’s in the same slot as me.  Maybe we can get the guys to record the sessions this year?

Tags:

Silverlight | Technical Community | Architecture and Design

Binary Drop For the Task Parallel Library for Silverlight

by Damon Payne 13. February 2011 18:45

Since there was interest, I am doing a binary drop of my port of the Task Parallel Library for Silverlight 4.  Please contact me with feedback, bugs, and suggestions.  Once I’m done with some more performance–centric unit tests I will post the source code as well.  I’d like to have something set up that shows this off within a Silverlight app.

Download the binaries here.

Tags:

Silverlight | Parallel

Task Parallel Library Ported to Silverlight 4

by Damon Payne 7. February 2011 19:02

Long time readers will recall that I’ve done some oddball parallel articles over the years.  I recently decided to challenge myself with porting the Task Parallel Library to Silverlight 4.  The port is complete and all unit tests pass.  I’m still profiling but I’m generally encouraged by the results.

Why?

A fair question.  Why do I need libraries for making it easier to write multithreaded code in Silverlight? 

First, Silverlight is making big strides as a platform for Business applications.   Business applications might be able to absorb extra computing power on the client machine.  I envision data analysis applications doing lots of work on the client PC.  Silverlight Games might be another case when you are doing a lot of game-world updating or computations yourself.  What about popular distributed computing applications like Folding @Home or SETI? 

Then, of course, there’s the fact that we find ourselves doing minor threading work on Silverlight applications already today.  For example, at work I have a Silverlight application which imports data from very large Excel files on background threads.  The fact is that the Task model, the Cancellation Token model, and the Concurrent Data Structures are just really nice programming models.

Comments on the TPL Port, and Porting in General

I didn’t start from scratch.  The Mono Project has been working on an implementation for their .NET 4 stack.  Most of the credit, then, goes to Jérémie "Garuma" Laval.  I grabbed all of System, System.Collections.Concurrent, System.Collections.Concurrent.Partitioners, System.Threading, and System.Threading.Tasks and brought things in one class at a time as I needed them to get System.Threading.Tasks to compile.

Some comments on the port:

  • Serializable –  A good example of something that’s missing from Silverlight.  I find that I tend not to comment these things out but rather make an attribute that does nothing.  If Silverlight supports this in the future or I discover something useful I could do the mock version is nice.
  • No Thread.Yield in Silverlight – I was worried things like this being missing would kill this port.  After doing some research, replacing these with Thread.Sleep(0) should have the desired effect.
  • No Interlocked.Read in Silverlight – I’m most worried by this omission.  Interlocked.Read allows you to do atomic operations on long integers in a 32bit process, which Silverlight always is until Silverlight 5.  I don’t have pointers or any other workarounds that I could think of either.  This means in the work-stealing portions of the Queues that parallel tasks use I have some operations that need to be atomic but aren’t.   I may go back and change these to 32bit integers.  No one wants to wait on a long integer’s worth of Tasks anyway. 
  •  No Thread priority in SIlverlight- The task parallel library portions that dealt with thread priority had to be #-defined out.
  • Array.Convert() – Missing from Silverlight, but easy to re-create as an extension method.

Performance and Source Code

I am doing some profiling to see if there’s anything I can do to increase performance.  Running the same unit tests on this port and the full .NET framework has revealed that this code isn’t as fast on Silverlight.  Still, as I said I think having this programming model is pretty nice even without perfectly linear per-core speedups. 

I will release the source code if there’s interest.  I believe the Mono license allows me to do this as long as I leave their license in tact in the the source files.  I should definitely head out to user voice and ask for some of these features in a future version of Silverlight.

Tags:

Silverlight | Parallel

Vote for my MIX2011 Sessions

by Damon Payne 25. January 2011 14:12

My proposals for MIX 2011 have made the initial cut and are on the MIX Open Call site for voting!  Even if you're not going to MIX, head over to http://live.visitmix.com/OpenCall and vote on what sounds interesting.

You can read about my proposals at:

Advanced MVVM Techniques for Silverlight Business Applications http://live.visitmix.com/OpenCall/Vote/Session/130

WCF Patterns and Practices for Silverlight http://live.visitmix.com/OpenCall/Vote/Session/131

Wish me luck! 

Tags:

Silverlight | Technical Community

About the author

Damon Payne is a Microsoft MVP specializing in Smart Client solution architecture. 

INETA Community Speakers Program

Month List

Page List

flickr photostream