Today with Guido Maliandi, we set to find a way to use the Accordion from the Silverlight toolkit as region in a Prism application. As the Accordion inherits from ItemsControl, Prism already provided some functionality to get that control working as a region. However, we wanted it to have the following behavior:

  • Only one view in the accordion region should be active at a time.
  • It should be possible to set the header for each AccordionItem.
  • It should be easy to extend with other required functionality.

If you are familiar with Prism’s source code, you might probably notice that is quite similar to the way Prism handles Silverlight’s TabControl as a region. Our approach was creating two classes:

  • AccordionRegionAdapter: This class would be in charge of creating the region and hooking it up with the control.
  • AccordionRegionSyncBehavior: This class would provide the region’s functionality.

Any other functionality that was necessary could be added through other RegionBehaviors. This document from the Prism documentation explains the usual process of creating a custom Region Adapter.

As the code for both those classes is quite long, I decided to simply provide the download at the bottom of this post.

Setting the AccordionItem’s Header Text

As it can be done with the TabControl region, the following syntax can be used to show some text in the header of each AccordionItem (in this case the View’s DataContext is simply a string). The outcome can be seen in the picture placed after the code.

<tk:Accordion Name=MainRegionRegions:RegionManager.RegionName=MainRegion>
  <shell:AccordionRegionAdapter.ItemContainerStyle>
    <Style TargetType=tk:AccordionItem>
      <Setter Property=HeaderTemplate>
        <Setter.Value>
          <DataTemplate>
            <TextBlock Text={Binding}/>
          </DataTemplate>
        </Setter.Value>
      </Setter>
    </Style>
  </shell:AccordionRegionAdapter.ItemContainerStyle>
</tk:Accordion>
Sample Application

image

I created a small sample application which shows this scenario working. You can download it from here. The code is provided “AS IS” with no warranties and confers no rights.

I hope you can make good use of it.

Shout it

The holidays are over, happy new year everyone and I hope it is a good one for all of you. It’s time for the first post of the year, which continuing last year’s trend will deal with Prism.

A couple of weeks ago this question in the Prism forum got Fer and I thinking how to set the name of views in a region using View Discovery. As Prism does not support this out of the box (which is kind of weird), we had a talk with Ezequiel and Julian and decided to use Prism’s extensibility to get this done (this means not changing the Prism source code at all :) ).

A couple of changes needed to be performed to achieve this functionality:

  1. Create a new RegionViewRegistry. Its API would allow passing the name of the view as the parameter when registering it with a region:
  2. public interface IRegionViewWithNamesRegistry : IRegionViewRegistry
      {
          void RegisterViewWithRegion(string regionName, Type viewType, string viewName);
          void RegisterViewWithRegion(string regionName, Func<object> getContentDelegate, string viewName);
      }

  3. Extend the AutoPopulateRegionBehavior to register the view using its name. To get this done we inherited from the RegionBehavior base class.

Finally to check that everything worked correctly we created a small sample using the ViewDiscovery-UIComposition QS for Silverlight (the new registry and behavior must be registered in the bootstrapper).

You can download the code from here (use the ViewDiscoveryComposition.sln). The code is provided “AS IS” with no warranties and confers no rights.

Shout it

About a week ago in the Prism forum we got a question about an issue in the scenario displayed below.

The Issue

When the MainView was removed from the MainRegion, the RightOne and RightTwo regions were not removed from the RegionManager and the views were still being referenced by the region. We were able to reproduce this issue “successfully” both using scoped regions and without them so we started thinking on a possible fix for this.

The Fix

After trying different things out, we took Julian’s suggestions and created a RegionBehavior that would be in charge of this. You can find the complete code for this class below:

public class ClearChildViewsRegionBehavior : RegionBehavior
   {
       public const string BehaviorKey = “ClearChildViews”;

       protected override void OnAttach()
       {
           this.Region.PropertyChanged +=
               new System.ComponentModel.PropertyChangedEventHandler(Region_PropertyChanged);
       }

       void Region_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
       {
           if (e.PropertyName == “RegionManager”)
           {
               if (this.Region.RegionManager == null)
               {
                   foreach (object view in this.Region.Views)
                   {
                       DependencyObject dependencyObject = view as DependencyObject;
                       if (dependencyObject != null)
                       {
                           dependencyObject.ClearValue(RegionManager.RegionManagerProperty);
                       }
                   }
               }
           }
       }
   }

When the RegionManager property of a Region changes to null, the behavior removes the view’s RegionManager attached property of all views in the region. Adding this behavior by overriding the bootstrapper’s ConfigureDefaultRegionBehaviors will enable this behavior for all regions:

protected override IRegionBehaviorFactory ConfigureDefaultRegionBehaviors()
        {
            var regionBehaviorTypesDictionary = base.ConfigureDefaultRegionBehaviors();
            regionBehaviorTypesDictionary.AddIfMissing
                (ClearChildViewsRegionBehavior.BehaviorKey, typeof(ClearChildViewsRegionBehavior));
            return regionBehaviorTypesDictionary;
        }

The Outcome

I have created a sample application showing how the fix works. You can download it from here. The code is provided “AS IS” with no warranties and confers no rights. I hope you can find this behavior useful if you have a similar kind of situation in your application.

As I probably won’t blog anymore until after the holidays, have a merry Christmas and a happy new year :) .

Shout it

As I thought this is a question that could interest many people, instead of answering this question directly in the Prism codeplex forum I decided to create a short blog post and answer it here.

The answer is “kind of”. Silverlight 4 Beta, so far, only supports binding commands to controls that inherit from ButtonBase (Button and HyperlinkButton), as you can read in Tim’s and Mike’s posts.
Therefore, if you are using Prism, these are the things that you will not need any more, and those that you will:

No longer necessary

ButtonBaseCommandBehavior and Click classes from the CompositePresentationSilverlight assembly. As these are used to hook the command and the click event through XAML, you can bypass this by using the new command support.
<Button Content=SaveCommand={Binding Path=SaveOrderCommand}/>

Still necessary

As there is not an actual implementation of the ICommand interface, the DelegateCommand and CompositeCommand are still useful. Also, as controls other than Buttons do not have the possibility to bind their events to commands in the ViewModel, using attached behaviors is a good approach. You can use this code snippet to simplify the work.

Wrapping up

I hope this helps clarify this topic a bit, and if you have any doubts drop by the Codeplex forum and ask away (if you are shy you can always leave me a comment).

In case you want a working sample, I have made a couple of changes to the Commanding Quickstart to use the Command property instead of Prism’s attached behavior. You can find it here. The code is provided “AS IS” with no warranties and confers no rights.

Shout it

kick it on DotNetKicks.com

Most of you know that a Silverlight 4 Beta was released last Wednesday, after Scott Gu’s PDC keynote. If you are a Prism user, and if you are reading this there’s a high chance you are, you are probably wondering how this relates to p&p future plans. Well, Blaine has given us a brief idea of Prism’s future in this forum thread, so you might want to check it out.

On a related but different subject Fernando and I migrated the latest Prism release to Silverlight 4 Beta version & Net 4.0. A few minor changes needed to be done in the code (explained here), and some other in the .csproj files due to an issue we came up using the Silverlight migration wizard.

Migration Issues

After going through the migration wizard, you will notice that all Silverlight projects are not loaded. This is because they are still looking for the 3.0 installation directory instead of 4.0 as you can see in the picture below.

image

To fix this issue you need to edit your .csproj file and redirect it to the Silverlight 4 directory. The line that is related to this issue is the following:

<Import Project=$(MSBuildExtensionsPath32)\Microsoft\Silverlight\$(SilverlightVersion)
\Microsoft.Silverlight.CSharp.targets/>

Here you have two options:

  1. Replace “$(SilverlightVersion)” for “v4.0″.
  2. Modify any existing declarations of “SilverlightVersion“ in your file and update them to 4.0. Take into account that some of them might be using the “FrameworkVersion”. The code below shows this situation:
    <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
    <SilverlightVersion>$(TargetFrameworkVersion)</SilverlightVersion>

Prism Migrated Download

If you want to save some time, you can download the CAL, Quickstarts and RI from here. The code is provided “AS IS” with no warranties and confers no rights and is shipped under the “works on our machine” license.

Have fun coding in Silverlight 4!!!

Shout it

kick it on DotNetKicks.com

On a previous post in this series I talked about a possible approach to take when starting to learn Prism as a whole (the Tip numbering is resumed from the previous post). In this post I will get more specific and talk about one of the most used (if not the most used) pattern when developing Prism applications (either for WPF & Silverlight): MVVM.

Most people are familiar with this pattern (if you are not great places to read about it are here for WPF and over here for Silverlight), so I will not go deep into what is the main idea of it. Instead I will try to go over some core concepts that usually lead to different levels of confusion.

What’s the difference between MVVM and PresentationModel?

The above question is one asked a lot, as people tend to get confused when they hear all the talk about MVVM and then open some Prism Quickstarts or RI and find most of them “implement the PresentationModel pattern”.

Well, there is not a certain answer (and if there was I probably wouldn’t be the one who came up with it), but as far as Prism development is concerned they are synonyms. There is no difference between them, except for the coined term. As Martin Fowler explains in his PresentationModel article: “The essence of a Presentation Model is of a fully self-contained class that represents all the data and behavior of the UI window, but without any of the controls used to render that UI on the screen. A view then simply projects the state of the presentation model onto the glass.”, so if you think about it, the way to “project the state of the PresentationModel (or ViewModel) onto the glass is WPF/Silverlight DataBinding in our case (or as Julian likes to explain it: “the ViewModel is a bindable Presenter”).

Always remember the main objective, testability and decoupling.

Tip 5: MVVM and Presentation Model are synonyms.

How do I do pure MVVM?

This is another point of confusion as people tend to relate MVVM with DataTemplates and no View code behind, so they get the idea that the only way to implement the pattern is that one.

In my opinion there is no pure MVVM, it is a design pattern, so it can have many different implementations which will depend mainly on who implements it and what his requirements are. In this particular topic I would like to “branch you” to Glenn’s post “The spirit of MVVM (ViewModel), it’s not a code counting exercise.” as I agree with his point of view in this topic, so there is no point in duplicating the information.

Now that you have finished reading Glenn’s post, I hope you understand what I am trying to explain (not necessarily agree). I for once like the “View First” (you “talk” to the view) implementation to relate the View to its ViewModel in Prism could be the following (using DI):

public class MyView
{
public MyView(IMyViewModel viewModel)
{
this.DataContext = viewModel;
InitializeComponent();
}
}

In the code above, Unity’s DI provides the decoupling between the View and the ViewModel, so the ViewModel “does not have to know anything about the view” and allows you to test the VM in isolation (of course this is just one of the ways to do it).

Tip 6: There is no Silver Bullet MVVM implementation. Use the one that you like best.

How should I manage my View/ViewModel?

This question addresses both creation/destruction of View and ViewModels as well as its interaction with other components in the application. Often it is not “clear” which component should handle a specific action.

Say that when a button is clicked an event should be published. Where should this be done? Well, without information about the application and its patterns it is hard to say. It could be done in the ViewModel or it could be done in a module level controller that manages interaction with other modules, but this depends on how your application is structured.

Instead of expanding on this topic, I would like to branch you (yet again), to these posts from Ward Bell which talk about these common questions and provide some really interesting and thought answers:

Should I always use commands to communicate with the ViewModel?

Before using a command, I usually stop and think: “Can this be done in another way?, Can I achieve this same functionality with binding?”. Well, sometimes the answer is yes, and that is when I think commands are not necessary. The most common example is binding a command to execute every time and item in a Listbox is selected. This same behavior can be achieved by binding the SelectedItem property of the Listbox to your ViewModel (most of the times), and executing the required action on the setter.

Having thought of the above, what if I do need a command? Well, my first recommendation would be understanding how do Commands with attached Behaviors work, a topic explained by Julian in this great post. After that you can use the code snippet I created some time ago to help you with the tedious task of creating the classes required for this to work.

Tip 7: Before using commands, think if there is another option.

Things to add to your reading list

To help you comply with Tip 4, you can find below a couple of articles about MVVM and MVVM with Prism that I think might be of use to better understand this topic (the ones mentioned above would be in this list, but there is not need in duplicating them):

Hopefully, this post has helped you understand a little more about MVVM and how to use it with Prism. As always, your feedback is appreciated, so if you believe any link should be added or anything of the sort, just drop a comment.

Shout it

kick it on DotNetKicks.com

As most of you might know, Visual Studio 2010 Beta 2 was released some days ago. Ever since, many people have asked at the Prism codeplex forums if Prism works with this latest version. That’s why with Fer we decided to migrate Prism latest release for Silverlight 3 to VS 2010 Beta 2. Our conclusion after our smoke tests is that it does work :) .

Migration Steps

  1. Migrated every solution.image
  2. Ran the tests and smoke tested each application.
  3. Fixed any issues that appeared (mostly related to missing assembly references).
  4. As a little extra, we added the White assembly references required to run the acceptance tests.

Changes Required

Below you can find a small explanation of the changes required for the migration:

  1. The Reference Implementation Tests fail (4 tests) when you run them. The fix is explained in this thread.
  2. Many projects will throw a missing assembly reference exception related to “System.Xaml.dll”. You need to add this assembly as a reference in most test projects.
  3. The Multitargeting Quickstart throws an error when running it. To fix it, change the Resources constructor modifier from internal to public.
  4. Some build errors might be thrown because of code analysis issues in Silverlight projects (CA:0055 Analysis of Silverlight assemblies is not supported):
    • Uncheck the “Enable Code Analysis on build” check box in the Code Analysis tab.
    • Make sure code analysis is not one of the compilation symbols in the Build tab.

Download

The code provides all the fixes performed, and is provided “AS IS” with no warranties and confers no rights. It is shipped under the “works on my machine” license. You can download it from here.

I hope this saves you the trouble of migrating Prism to VS 2010.

Shout it

kick it on DotNetKicks.com

Now that the Prism team has shipped a new version of the guidance, I thought it would be a good time to blog on this subject, based on some research we did with Ezequiel, Matias and Julian. This article will not focus on how to workaround the limitations of using Silverlight 3 Navigation with Prism (as the guys who wrote the posts mentioned below have done a good job on that) instead it will focus on the why of these limitations:

Warning: Technical explanation coming below.

The Silverlight team is aware of the limitations mentioned below, so they might be taken into account for a future version.

Issue Description

Pages with code behind, from remotely loaded modules cannot be navigated to, calling the Frame’s Navigate method. This prevents having functional views since they neither have code behind nor a ViewModel attached.

Cause of Issue

Note: To be able to perform the research below, add the following line in the LoadAssemblyFromStream method placed in the XapModuleTypeLoader class from the CAL:
Deployment.Current.Parts.Add(assemblyPart);

The Silverlight 3 Navigation framework goes over every AssemblyPart in the Deployment.Current.Parts collection if the Page to navigate to has code behind, as shown in the code below (PageResourceContentLoader class reflected code in the System.Windows.Navigation namespace from the System.Windows.Controls.Navigation assembly):

private static Type GetTypeFromAnyLoadedAssembly(string typeName)
        {
            Type type = null;
            foreach (AssemblyPart part in Deployment.Current.Parts)
            {
                /*THE LINE BELOW RETURNS NULL FOR REMOTELY LOADED ASSEMBLIES, BECAUSE THEY ARE NOT IN THE APPLICATION’S XAP*/
                StreamResourceInfo resourceStream = Application.GetResourceStream(new Uri(part.Source, UriKind.Relative));
                if (resourceStream != null)
                {
                    Assembly assembly = new AssemblyPart().Load(resourceStream.Stream);
                    if (assembly != null)
                    {
                        type = Type.GetType(typeName + “,” + assembly, false);
                    }
                }
                if (type != null)
                {
                    return type;
                }
            }
            return type;
        }

As the above code shows, even if the AssemblyPart is in the collection it is not found by the Application.GetReourceStream method. From the method’s MSDN site, the cause is:

“The GetResourceStream method allows you to load an arbitrary resource file from one of the following locations:

  • Embedded in the application assembly in the application package.
  • Embedded in a library assembly that is included in the application package.
  • Included in the application package.”

So only assemblies in the application’s original .xap file are found and not for other modules.

I hope the above explanation was useful.

Shout it

kick it on DotNetKicks.com

The patterns & practices team has just released Prism-v2.1, an updated version of the Composite Application Guidance for WPF & Silverlight, which has some breaking changes, mostly related to Silverlight 3 (from the “New in this release” article):

image

  • All Visual Studio projects (Composite Application Library, reference implementation, and Quickstarts) were migrated to use Silverlight 3.
  • TabRegionControlAdapter was modified to support binding in the TabItem’s control header in Silverlight 3.
  • CreateXap.bat file was modified to search for Silverlight 3 assemblies if the Silverlight 2 reference assemblies cannot be found.
  • Implemented the WeakEvent Pattern for the DelegateCommand’s and CompositeComand’s (more on this below).

If you were using Prism 2.0, either for WPF or Silverlight development, I would recommend you to start using this new version, as there is also an implementation “of the WeakEvent Pattern for the DelegateCommand’s and CompositeComand’s CanExecuteChanged event to fix a possible memory leak in the applications using the Composite Application Library commands”.

You can download the latest version of the guidance from here.

Kudos to the Prism team!!!

Shout it

kick it on DotNetKicks.com

A question we get asked frequently is: “How do I start learning Prism? Is there a particular order for the Quickstarts? What other web resources do you recommend to start learning?”. If you are in this situation, or just want to have some more insight on a particular Prism topic, this is the post for you (I always wanted to say that, just like TV announcements :))

The basic question: “How do I start learning Prism?”

The first thing you should do to start learning Prism (assuming you know WPF/Silverlight), is begin with the documentation. It is really clear in what it tries to explain, provides great samples and explains a lot of the common doubts when starting to develop applications with Prism. There is not a particular order to learn Prism, so you should tackle it in the way you feel comfortable. Pay special attention to the Technical Concepts section, as it really helps understand how things come together.

Tip 1: Read the Prism documentation.

If while reading the documentation you have any doubts, or want to dig deeper into any particular topic you have many different options (and search queries in your favorite search engine). However, there are some things I believe you should take a look at:

  • Prism KB. There you will find links on many different topics (you can find a picture of them below), that could be videos, sample applications or blog post which will help you better understand some of Prism concepts.
  • Watch videos. There are lots of video tutorials going around, but these two collections are particularly good. Videos from P&P team & 10 Things to Know About Silverlight Prism.
Tip 2: Use the Prism KB and watch videos (these and also these particularly).

image

Prism KB site

But, what if I have some doubts while learning?

That is why developer communities were created, and as any other p&p asset Prism has its own forum at Codeplex where you can ask questions about any topic (technical concepts, how do I?, etc). The forum has a really active community, and is also monitored by the p&p Client Sustained Engineering Team (which we are part of). So if you have a question that has been bugging you for some time, and have not found the answer anywhere you can always drop by the forum.

Tip 3: Ask questions in the Prism Codeplex forum.

Last, but definitely not least…

There are some frequent Prism bloggers that you should follow, as they have some really interesting posts about how to use Prism and its insides. Below I will provide the list of those I follow (which is probably really short in comparison to the one I should be following), and for some the most interesting/requested post in my opinion:

As an extra, you can also follow the clientdev twitter, in which we tweet about the latest news about different .Net Client Development technologies (mostly Silverlight & WPF) and can be really useful when learning about Prism.

Tip 4: Read tons of articles about Prism.

I hope this article will help your Prism learning process, and please provide any feedback you might have so I can improve this guidance, like comments on the bloggers.

Shout it

kick it on DotNetKicks.com