Monday, October 29, 2012

Portable Class Libraries [PCL] : Targeting Additional Frameworks

In this post, we will continue our discussion on Portable Class Library in Visual Studio. This allows us to target the same assembly to multiple frameworks, which allows to use the same assembly without even a need of recompilation.

Previously we have discussed about the following:
  1. An Introduction :
  2. Portable Class Libraries & MVVM :
  3. Portable Class Libraries & Features Support using Profiles :
  4. Portable Class Libraries & Type Forwarding :
As we know that the portable class library tools now support targeting the library to multiple frameworks including .net framework versions, silverlight versions, Windows Phone versions, Windows Store App and Xbox 360. What if we want to target it to a .net platform which is not listed including mono platforms?

Targeting additional Framework & Usage of Profiles
In order to determine how we would be supporting the framework in Portable Library Tools, we first need to determine the feature set supported by the target framework. We must also consider how those features are supported. During our type forwarding related discussion for portable libraries, we tried to ponder on why it is important to know how the features are provided and that is why MVVM types are not supported with portable class libraries for .net framework 4.0 as they are differently provided than rest of the platforms.

These profiles allow Visual Studio to provide framework lists for portable class library projects. Based on this idea, we should be able to add remove the frameworks and their versions by manipulating these profile folders. To get started, let's move all the profiles from the .NetPortable folder.

Now create a Portable Library Project and see the empty target framework lists. Now it should make sense how profiles affect the target frameworks list available for portable class library projects. I am using Visual Studio 2012 RC here.

Skeleton of a Profile
As sample profile folder for a portable class library project consists of some dlls & their xml for documentation of containing types, RedistList folder and SupportedFrameworks folder.

Here all the dlls are retargetable. This means that the portable library would use the versions of these dlls from the host framework. So if the portable library is being used in a Silverlight project then it would be using the Silverlight version of these assemblies. Similarly, if the same assembly is being used in a .net framework based project, it would be using the assembly provided by .net framework version. Let's look at the manifest of System.Core assembly in Profile1. You can also notice that the other assembly references are also from retargetable versions of these assemblies.

Al the profiles seem to share the code documentation. So the xml files contained in the profile folder is just for redirection to the main folder containing all the profiles.

This is just referring to this documentation xml file. This is super smart idea as the main folder would have the complete documentation and all the containing profiles would just be a subset of the main assembly.

Please remember to reload visual studio i.e. kill it and open it again for the changes in profiles to take effect.

Now we come to RedistList/FrameworkList. This is to describe the list of assemblies available for the target frameworks. For Profile1, the list is as follows:

From the xml file, I am sure that you can guess what assemblies would be looked for for the list of the target frameworks. The corresponding assemblies are looked for in the folder containing the Redist folder. There seems to be no exception if an expected assembly is not there in the folder. Also there doesn't seem to any issue if an unexpected assembly is found in the profile folder.

Now which part of profile is important to show frameworks and their versions in framework selection dialog for portable class library project. This is the SupportedFrameworks folder. You will find a list of xml files in the folder.

The text of the framework for the selection comes for the xml content of these files. Display name shows up for the selection. If we just change Xbox 360 to Xbox 360 2 , that is what is shown on the dialog for selection.

This is how the framework selection is shown after the change:

And that is exactly how this is shown in the Library Tab of Portable Class Library project.

Now on Additional Frameworks
After the above discussion, we have found out that the frameworks available for selection are picked up from the xml files from the SupportedFrameworks folder. So in order to target to an additional framework, we need to find out if the new target framework has features that are provided by any of the available profiles. And also the way the profiles are provided.

This is how the framework is available in the selection dialog:

If there are more than one versions of your framework in different profiles then they are displayed in a selection control. Let's copy a new profile [Profile 2] and a new framework file Additional Framework 2.0 with the following contents.

This should result in displaying the framework selection dialog as follows:

Tuesday, October 23, 2012

Issues / Bugs with Assembly References in Portable Class Library Projects

As we know that a portable class library can only reference other portable library projects. For this example, we are using Portable Library Tools 2 Extension installed through Extension Manager in Visual Studio 2010.

There seem to be two rules for assembly / project references in a portable class library project.
  1. Portable Class Library Project can only reference other portable class library projects / assemblies.

  2. The project where the reference is being added must have compatible set of framework selection as the project / assembly whose reference is being added. This compatibility is difficult to understand. Basically the available features set of the source assembly / project must be same or smaller than the target project. This happens when the source project / assembly is either targeting the same set of frameworks or has more framework selections than the target portable class library project.
There are two issues with assembly references in Portable Class Library Project.

No Checks for Portable assembly references:
The only verification for assembly references seem to be that the source assembly must be a portable library. It doesn't seem to verify the platform selection of the source assembly.

Let's look at the sample solution with two portable class library projects as follows:

The platforms selection of the PortableSourceLibrary and PortableTargetLibrary is as follows:

From the platform selection it is apparent that PortableSourceLibrary is targeting a bigger subset of features than the PortableTargetLibrary project. Based on the rules discussed above, a reference of PortableClassLibrary project can be added to the PortableSourceLibrary project.

For the same reason vice versa is not true i.e. when we try to add a reference of PortableSourceLibrary into PortableTargetLibrary, the IDE doesn't allow so and shows the error notification dialog. But when we try to add the assembly reference instead of the project reference, it doesn't show the same behavior.

And it silently adds the reference.

This is definitely a different behavior than the project reference and it needs to be requested to be fixed.

No Verification when the target platforms for source portable library project is updated:
Portable Class Library project checks whether the source portable library project has the compatible platforms selection as the current project. But it seem that this is only checked when the reference is being added. Once the reference is added then we can change it to an incompatible platforms selection and this would still build fine.

Let's again add PortableTargetLibrary project reference into PortableSourceLibrary project.

Now select the PortableTargetLibrary project and update the target frameworks as follows:

Now this is the combination which would be an issue if we add a fresh reference of this project to PortableSourceLibrary project. But there doesn't seem to be any issue now when the reference is already added.

Please note that the project having the references does report issues when we unload the project and try to load it again. We can't load it unless we update the target platforms for the source project being referenced.

I have reported the issue on Microsoft Connect. Please vote for this.


Sunday, October 21, 2012

Boston Code Camp Oct 2012

It has been a great experience participating in Boston Code camp as a speaker. As always, the code camp was an opportunity to have great technology conversations with like minded technology enthusiasts. Packt gave me three free ebooks and a 20% discount code for the folks who attended the event.

With Nick Parker and Ben Lambert

With John Zablocki

With Bob Goodearl and other codecamp presenter

Sunday, October 14, 2012

Ribbon - Quick Access Toolbar & RibbonWindow : WPF 4.5 RC New Features

This is a series of post in which have have been discussing the new features of WPF 4.5 RC. In the last post we started our discussion of Ribbon feature in the framework. I have been Ribbon as a new feature because it is a lot more than a control. With the Selector control for Ribbon, it has introduced a lot of other controls including RibbonButton, RibbonComboBox inheriting from the base ContentControl(s) like Button and ComboBox. In this post we will be discussion Quick Access Toolbar and RibbonWindow.

Quick Access Toolbar
Toolbars have historically been used to group together frequently used commands in a desktop applicaiton on Windows Platform. They have been provided to provide ease in the use of the system. They can also be used with the ribbon. Here it is called Quick Access Toolbar. Although we can add / remove items from the Quick Access Toolbar, we can also provide users the ability to modify the toolbar by adding or removing items from it.

Although Quick Access Toolbar is a part of Ribbon, it can be displayed on top or bottom of the ribbon. We can also display it on application title bar by using RibbonWindow instead of regular WPF window. Quick Access Toolbar is displayed irrespective of the ribbon tab selected. If the quick access toolbar is already displayed on bottom of the Ribbon then user can always move it back to the top.

In the following example we are adding a Quick access toolbar to our Ribbon control. The toolbar has two buttons hosted inside a DockPanel. As we learnt before, we need to set the Label property of the button instead of WPF Button where we set the Content property to set the text displayed on the button.

This toolbar would be displayed as follows in a RibbonWindow:

If the toolbar cannot accomodate all the items on the title bar because of the size limitation, then the items are displayed in a drop down as follows:

I added the above elements using the follwing xaml:

Ribbon Window
Ribbon Control is a Selector control which can be hosted in a regular WPF Window. But there are benefits of hosting it in a RibbonWindow.

Although you might not find RibbonWindow in "Add New Item" dialog, you can simply add a regular WPF window and update the Xaml to change it to a RibbonWindow as follows:

Please make sure that you are referencing System.Windows.Controls.Ribbon as we did in our previous post. You can also update the code behind as follows:

Please have a look at the title bar of Microsoft Power Point 2010. The title bar is displayed as follows:

You clearly can see that there are controls added in the non-client area of the Window. This is Title bar. Historically we have just seen Title property which can only be assigned with a string value, and that's it. Basically we can achieve the same behavior by using RibbonWindow instead of regular WPF window. RibbonWindow allows the Quick Access Toolbar and Contextual Tab Headers to be drawn in the non-client are of the title bar.

If we set the title on RibbonWindow and Ribbon both, then the title set on the RibbonWindow is preferred for display by the runtime. In the following example, you can have a look that we are setting both of these properties.

And the view is displayed as follows:

Wednesday, October 10, 2012

Ribbon : WPF 4.5 RC New Features

This is a series of post in which we have been discussing new features in WPF 4.5. In this post we are starting a sub-series discussing Microsoft Ribbon features and controls provided with the new framework. This is part of the release in Visual Studio 2012 RC and there is no separate download required unlike Visual Studio 2010. For using the ribbon with Visual Studio 2010, it can be downloaded from here:

Download for Visual Studio 2010

System.Windows.Control.Ribbon Assembly
In order to use the controls for ribbon, System.Windows.Control.Ribbon assembly must be referenced in your WPF project.

Class Hierarchy
Ribbon is a Selector control. The class hierarchy of Ribbon control is as follows:

This post would start the Ribbon disucssion with a an introduction of Ribbon Application Menu. The post would discuss different components of the menu and how we can use them in our application design.

Ribbon Application Menu
Ribbon Application Menu is the blue drop down you generally see on the top left side of the Ribbon. Different components of Ribbon Applicaiton Menu can be identified as follows:

They are combined together to form a dispaly worthy Ribbon Application Menu.

Ribbon Gallery for Auxillary Pane Content
Auxillary Pane is generally used to hold the items which can be provided for easy access for the client. It can hold recently or frequently used items by the user. You can also use it to provide user with the functionality to pin items for ease in future access of these items.

Most of the examples that you would see would be using RibbonGallery for Auxillary Pane. It is an ItemsControl. The gallery can be used to hold items of RibbonGalleryCategory which is a HeaderedItemsControl.

Here pinnedItems and recentItems are the resources to hold pinned and recent items. For simplicity sake, let us declare them in xaml as follows:

The above xaml would render the auxillary pane content view as follows:

It RibbonGalleryCategory use WrapPanel for laying out its items. But in actual if we snoop this we can easily find out that it uses RibbonGalleryItemsPanel which seems to layout its items like a wrap panel.

Let us update the ItemsPanel so that it uses StackPanel to display its items as follows:

This should apply the template for all the RibbonGalleryCategory items in the RibbonGallery. If we need to update the ItemsPanel for a wider scope then we can define this style in a wider scope including Window or App scope. The above code should update the display as follows:

Ribbon Application Menu's Footer Pane Content:
This is the Ribbon Application Menu's footer which typically hosts buttons that enable access to program options and the Exit command [msdn].

The above view can be obtained by just filling up the footer pane content using the following xaml:

Tooltip for Ribbon Controls
Ribbon based controls including RibbonButton has been defined to show the tooltip in a real defined manner. Six different properties have been added to these controls. They are as follows:
  1. TooltipTitle
  2. TooltipDescription
  3. ToolTipImageSource
  4. TooltipFooterTitle
  5. TooltipFooterDescription
  6. ToolTipFooterImageSource
The above properties are used to create a tooltip. This is then assigned to the Tooltip property inherited from FrameworkElement. If you add the property value explicitly on the control or using TooltipService, then the explicit value takes precedence. The constructed Tooltip can be shown as follows:

The above tooltip can be obtained by setting the property values as follows:

The assigned instance to Tooltip property is basically an instance of RibbonTooltip. It inherits from Tooltip class.


Sunday, October 7, 2012

Weak Event Pattern Improvements : WPF 4.5 RC New Feature

In this post we are going to discuss improvements in WPF 4.5 RC for Weak Even Pattern. This introduces a mediator between event source and subscriber. The greatest thing is that it just maintains a weak reference listeners causing no memory leaks.

Some Background on Weak Event Manager
Event subscription cause memory leaks because Event Source holds strong references of the listener. Now listeners cannot be collected because garbage collection algorithms only get rid of those objects without any hard references. In order to handle this problem, idea of weak references came along. There is no need of maintaining any hard references for events. This is generally taken care of by introducing a mediator between a source and listener. There might be any number of sources for a source event from an instance. All the listeners should get notified when the actual event is raised.

Event sources must be defined in a certain way to publish these events. Before WPF 4.5, even listeners were needed to follow a certain pattern. They were needed to implement IWeakEventListener interface. As a developer, we don't want our class hierarchies to be effected by the API we use.

Improvements in WPF 4.5
In WPF 4.5 RC, weak event pattern is improved. In addition to listeners, WeakEventManagers also support Handlers. The handlers are defined like event handlers but our classes don't need to implement a particular interface. Plus since there are no hard references maintained, there are no possible memory leaks.

WeakEventManager is a DispatcherObject
You must notice that WeakEventManager is a DispatcherObject. Being a DispatcherObject it can't be used on a non-UI thread. This makes perfect sense based on the events it is introduced for. They are specifically UI related events.

Unit Testing & WeakEventManager
WeakEventManager doesn't implement any interface so it would be difficult to mock the manager's calls. This makes it more difficult to unit test the client code using WeakEventManager.

Difference with PRISM Event Aggregator / MVVM Light Messenger
We need to notice that this WeakEventManager is different than PRISM's EventAggregator or MVVM Light's Messenger. They are provided by their respective toolkits for messages publication and subscription. They are similar in the sense that they are also based on weak references. But they are very different in their usage. They are specially designed to support application wide messages for disconnected event source and subscribers. For the case of WeakEventManager, we need to specifically identify the source we are interested in.

Using Weak Event Manager
As a listener of these events, you need to use the appropriate WeakEventManager. There are basically few options available.
  1. Existing WeakEventManager
  2. WPF has provided a list of WeakEventManager(s) for the generally used events. You just need to find the appropriate event manager available for the event you need to subscribe. They all inherit from the abstract WeakEventManager class.

  3. Generic WeakEventManager
  4. If you can't find any specific WeakEventManager for your event, then the generic WeakEventManager can always be used. It actually uses reflection to find event given its name. It is also more verbose to use. That is why this can be our last option. But this relieves us from being worried about a particular WeakEventManager to be available.

  5. Custom WeakEventManager
  6. It would make more sense for control library authors to provide the WeakEventManagers for their events. In this way, the library users don't have to worry about using Generic Weak Event Manager causing possible efficiency issues. We just need to directly inherit from WeakEventManager providing definition of the overridable / abstract members.

Using IWeakEventListener
Before showing an example of how we can decorate a type to be a listener, let us first introduce some setup code. Here is ViewModelBase. It implements INotifyPropertyChanged which would allow our view models to support change propagation. We will be using this as base class of all our view models in this post.

Below is the view model to keep student info. A Student is being identified with StudentId. It also has a property called FirstName to keep the first name of the student. There is one more property IsDirty which is to identify that the Student info has been modified and it doesn't have default values for its properties.

Now we add a view model called MainViewModel. This keeps a collection of students maintained as ObservableCollection of StudentViewModel. It keeps adding an additional Student once the default student is modified.

The view model implements IWeakEventListener interface which requires the definition of ReceiveWeakEvent method. The method would get executed when any event is raised for which the object of this type subscribes as a listener. The implementation of the interface just shows that the object of this type can be used as a listener of weak events raised from WeakEventManager. In the method itself, we are just adding a new student, unsubscribing from listening the previous default student and add to listen to the new student view model instance.

SubscribeEventHandlers and UnsubscribeEventHandlers are the main code pieces in this example. It is here in these methods that the actual subscription and unsubscription of listener is taking place. We are just using the static methods AddListener and RemoveListener from PropertyChangedEventManager for this purpose. The WeakEventManager keeps a list of all subscribers and calls the ReceiveWeakEvent methods of all listeners whenever the specified event from the particular source object is raised.

Now lets use this view model in a view. The above view is being used as the MainWindow of the application. The above view model is being used as a DataContext of the view below. The Students collection is shown in a DataGrid.

Using WPF 4.5 WeakEventManager's Handler
In WPF 4.5, the weak event pattern is further improved. We are not required to implement IWeakEventListener for a type being served as a listener of an event. Now we can just add handlers instead. Using AddHandler and RemoveHandler methods of the event manager, we can add and remove handlers of these events. Here We need to specify the event source, event handler and the particular property identified by property name. Other managers might need other details.

Using Generic WeakEventManager
There is also generic weak event manager provided by the WPF 4.5. Although there are performance implications because the event is identified by a string parameter. So the framework would be using reflection to get the event details from the type. Since this is generic, we can't specify the particular property name here unlike the previous two methods.

Let us run the application, the view is show as follows:

When the view is shown, try updating the FirstName column of the last row and notice a new row being added.