Archive

Archive for the ‘Scrum Sprint Monitor’ Category

Runtime Intelligence support in VS2010

May 9th, 2010 Pedro Pombeiro 2 comments

Visual Studio 2010 comes with support for adding Runtime Intelligence to your software out-of-the-box (courtesy of PreEmptive Solutions). Runtime Intelligence allows you to implement something like Microsoft Office’s Customer Experience Improvement Program (think of it as the desktop equivalent of web analytics).

I have tried this with Scrum Sprint Monitor, and it really is as simple as sprinkling an Attribute on strategic places in your code to track the functionality you are interested in. With CodePlex providing support for acting as an endpoint for uploading those statistics right at each projects’ page, this makes for a very compelling proposition indeed.

This is the end result after a few minutes of integration:

Feature Overview

After having spent about an hour trying out this support, I came to the conclusion that there are still a couple of rough edges for broad adoption of this solution for serious Open Source projects. Here is my comment to Brandon Siegel’s post at PreEmptive Solutions’ blog:

UPDATE: Shortly after this blog was posted, PreEmptive got in touch with me and let me know they were knocking down roadblocks in order to make these open source stories a reality, and a solution should emerge within about a month. Great show on their part!

I think the product has great potential, and the CodePlex/PreEmptive partnership could become a great story. However, for that to happen for anything other than the simplest of projects, a couple of things would need to happen:
- Serious open source projects use some kind of automated build, which will not work with PreEmptive because the MSBuild task is only available for Pro licenses.
- The attributes that are required in the source code (unless someone would ever want to edit those values in the UI every time the software is to be released) depend on a PreEmptive-owned DLL that cannot be redistributed. As such, the Open Source project owner cannot upload the DLL to the project source code repository.

These two situations will make the proposition a deal breaker, which is a shame, considering the benefit that Open Source projects could reap with little effort (I have completed that effort for Scrum Sprint Monitor, but now I have my hands tied with this situation).

Best regards,
Pedro

Here is hoping that PreEmptive Solutions goes the extra mile to allow the Runtime Intelligence story to be a very successful one.

kick it on DotNetKicks.com

Shout it

Setting up a dedicated Scrum Sprint Monitor machine

March 4th, 2010 Pedro Pombeiro No comments

The other day I had to reinstall the machine that I had running Scrum Sprint Monitor. Having done the last installation over a large span of time, I had forgotten all the steps that are required to get a good set up, so I took some time to write down a documentation page detailing the process.

Categories: Scrum Sprint Monitor Tags:

A Busy State Indicator attached behavior

December 1st, 2009 Pedro Pombeiro 3 comments

Today I decided to encapsulate the circular progress indicator I use in Scrum Sprint Monitor in a reusable behavior. This served as a learning experience as well, since I had not yet had the chance to play with attached behaviors. My requirements were the following:

  • Have a behavior that displays an animation during long running operations. It should dim out a defined region in the UI, optionally preventing input into that region. All state transitions must be animated.
  • Have minimal impact on the logical tree.
  • Allow configuration of parameters, such as dim brush, transition duration, etc.

This problem turned out to be a perfect candidate to writing a behavior, and I needed only a few hours to crank it out. Here is a short video demoing it:

This behavior makes use of the simple and great Circular Progress Bar control by Sasha Barber, up on CodeProject. You can easily replace the control used for the animation though, should you require a different one.

Usage

The behavior has a simple requirement, that it can only be attached to a Grid element (I believe that is a requirement that can easily be satisfied, in most projects). The only required property is the BusyState property, which tells the behavior when to do its work:

<Grid DataContext="{Binding Path=ConfigurationViewModel, Source={StaticResource serviceLocator}}"
      Behaviors:BusyIndicatorBehavior.BusyState="{Binding IsBusy}"
      Behaviors:BusyIndicatorBehavior.TargetVisual="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Grid}}}">

The behavior works by adding a Visual Tree at runtime under the attached DependencyObject (the Grid). You connect your Busy state flag by providing a Binding to the BusyState attached property. There are a few other optional properties you can use, to customize things such as the dimming brush, the transition duration, margins, etc.

The source code is available for download from the Microsoft Expression Community Gallery. Do leave some feedback if you have any suggestions, or if you just find it useful.

If you want to take a look at source code that uses this behavior, head to the Scrum Sprint Monitor project at CodePlex, and search for Behaviors:BusyIndicatorBehavior.

Shout it

Animating a data-bound color property

August 17th, 2009 Pedro Pombeiro No comments

As I was going through the UI of the Scrum Sprint Monitor to introduce animations to the larger UI elements, one type of property was proving difficult to animate: the dynamic background color of some elements which were bound to Brush (or Color) properties of the ViewModel.

Picture this: you have a Color property that is currently Green. At some point it changes to Red. You would like the UI to update smothly, so you would not see the color jump from Green to Red. You are not able to do this in XAML with triggers and storyboards directly. The problem lies in the fact is that the Animation objects in XAML cannot be bound to dynamic values (see instances here and here), as they must be frozen for performance and thread safety reasons.

<DataTemplate DataType="{x:Type ViewModels:BuildStatusBackgroundViewModel}">
    <Grid Background="{Binding Path=BuildStatusColor}" />
</DataTemplate>

Therefore there is no point in trying to introduce triggers (be it EventTriggers or DataTriggers) in this Grid element. What I ended up doing is deriving a class from Grid and spawning the animation from code behind.

<DataTemplate DataType="{x:Type ViewModels:BuildStatusBackgroundViewModel}">
    <Controls:BuildStatusBorder />
</DataTemplate>

See the code-behind example here. I did encounter a pitfall while developing this approach. I ran into a “Cannot freeze this Storyboard timeline tree for use across threads” exception, when the animation was kicked off. I fixed this by cloning the existing property value, essentially removing any data binding from the property.

Hope this helps someone who is running into the same problem of animating transitions between databound properties!

Shout it

Animated WPF Panels (animating collection views)

August 14th, 2009 Pedro Pombeiro No comments

UPDATE: The same functionality is now available out of the box using the Blend 3 SDK, through the FluidMoveBehavior. Just drag that behavior to your container panel, and set the Duration and AppliesTo properties! The only difference is that easing functions are not yet supported in WPF. We will need to wait until WPF 4 is released.

Last evening I finally implemented a long awaited feature (by me!) in the Scrum Sprint Monitor: animated WPF panels. As the team members in the Sprint move up and down the list (an ObservableCollection<>), get added or removed, I always wished that change could be animated. My current knowledge of the WPF layout mechanism wasn’t sufficient to finish on that endeavor within a few hours, though.

I finally found a blog post that set me on the right path, on Ed Foh’s blog. Ed in turn was inspired by Kevin Moore’s WPF Bag of Tricks, which also includes an Animating Tile Panel.

Here is a video demonstrating the enhanced behavior of my AnimatedUniformGrid:

An AnimatedUniformGrid in action

Why those two solutions didn’t work for me

Both of the aforementioned solutions contained hardwired positioning logic, though. I simply needed to add the animation behavior to StackPanel, WrapPanel and UniformGrid, not a completely custom panel. Ideally, the solution would be a behavior that could be added on top of those containers. That particular aspect wasn’t realized, and I ended up deriving classes for each of these panels, prefixing the new classes with “Animated”. It is still a pretty acceptable solution. UPDATE: I eventually found this was the same approach taken by at least one commercial offer.

The following is the code required to instantiate the uniform grid (note how you simple need to prefix the panel class with Wpf:Animated):

<ItemsControl ItemsSource="{Binding TeamMembersIncludingUnassigned}">
    <ItemsControl.ItemsPanel>
      <ItemsPanelTemplate>
         <Wpf:AnimatedUniformGrid Duration="00:00:01" />
      </ItemsPanelTemplate>
   </ItemsControl.ItemsPanel>
</ItemsControl>

 

Adding animation to an existing panel control class

The workflow for converting an existing Panel to an AnimatedPanel is pretty easy:

  1. derive a new class from the desired panel class (prefix it with Animated);
  2. override the ArrangeOverride method in the new class (don’t call the base class implementation);
  3. using .NET Reflector, extract the ArrangeOverride method contents from the base class implementation, and simply substitute the element.Arrange call that is performed for each child for a call to the AnimatedPanelHelper.ArrangeChild() static method.

That is all you need to do!

Acknowledgements

Thanks to Ed Foh and Kevin Moore for their great work.

Download the source code here.

Shout it
 
kick it on DotNetKicks.com

Writable machine-level AppSettings

August 12th, 2009 Pedro Pombeiro No comments

The other day I needed to make an application (a screensaver to be more exact) run under lower privilege in Windows 7. The application worked fine in Windows 2003, but something must have changed in Windows 7, because the screensaver was no longer running under my user account. In the end, this meant I had to move the application settings from User level to App level. It should have been a straightforward operation: simply change the level of each setting to Application, in the Visual Studio 2008 project settings page. The problem is that if you do that, the settings will become read-only.

A quick search through the web told me I would need to roll my own solution, using the ExeConfigurationFileMap class, and that is what I did at http://scrumsprintmonitor.codeplex.com/sourcecontrol/changeset/view/26836?projectName=scrumsprintmonitor#643147. Here are some observations about the implementation:

  • The settings file is hand-edited (no designer support, although the value of a designer here is negligible for a small app);
  • It has support for access in special scenarios, such as in a WPF designer;
  • It supports read-only scenarios, throwing an exception if you try to modify the settings.

Feel free to use it in your own projects.

Migrating NinjectContrib.CompositeWpf Bootstrapper to Prism V2

May 14th, 2009 Pedro Pombeiro 1 comment

For the last couple of days, I have been fighting with the Composite Application Guidance for WPF (aka Prism V2) after deciding to port an experimental version of the Scrum Sprint Monitor from Prism V1. It turns out that the ninject-contrib project where I got the Ninject bootstrapper from is still using an old version of the guidance. Long story short, it turned out that most of the problems I experienced stemmed from the fact that the bootstrapper has been significantly changed in V2, and I had not been able to find an article detailing the new layout of the bootstrapper, such as this one did for V1. The process of moving to the current version turned out somewhat painful, and I am documenting it here so that hopefully others can have an easier time going through the same process.

 

Updated NinjectContrib.CompositeWpf

I am attaching an updated version of the NinjectContrib.CompositeWpf project, now renamed to NinjectContrib.CompositePresentation so as to follow Prism’s naming scheme. You can drop that in as a replacement to the current version when migrating to V2.

 

Back to the problem at hand

I started seeing this error a lot:

"This RegionManager does not contain a Region with the name …"

Apparently, Prism V1 demanded regions to be registered before a module could register a view in it.

I set out to debug the problem. I banged my head around the DelayedRegionCreationBehavior class, wondering why the region was not appearing in the RegionManager – even though I could see it being created in response to the attached property declaration. I scoured the web for help, but no one seemed to be having the same issue (or they weren’t posting about it). Finally, on the second day I came across the UnityBootstrapper using .NET Reflector, and started seeing light at the end of the tunnel.

It turns out that some new methods and services were added in V2, missing from ninject-contrib’s implementation:

One of them adds some default behaviors:

/// <summary>
/// Configures the <see cref="IRegionBehaviorFactory"/>. This will be the list
/// of default behaviors that will be added to a region.
/// </summary>
protected virtual IRegionBehaviorFactory ConfigureDefaultRegionBehaviors()
{
    try
    {
        var defaultRegionBehaviorTypesDictionary =
            Kernel.Get<IRegionBehaviorFactory>();
        if (defaultRegionBehaviorTypesDictionary != null)
        {
            defaultRegionBehaviorTypesDictionary.AddIfMissing(
                "AutoPopulate", typeof(AutoPopulateRegionBehavior));
            defaultRegionBehaviorTypesDictionary.AddIfMissing(
                "ContextToDependencyObject",
                typeof(BindRegionContextToDependencyObjectBehavior));
            defaultRegionBehaviorTypesDictionary.AddIfMissing(
                "ActiveAware", typeof(RegionActiveAwareBehavior));
            defaultRegionBehaviorTypesDictionary.AddIfMissing(
                SyncRegionContextWithHostBehavior.BehaviorKey,
                typeof(SyncRegionContextWithHostBehavior));
            defaultRegionBehaviorTypesDictionary.AddIfMissing(
                RegionManagerRegistrationBehavior.BehaviorKey,
                typeof(RegionManagerRegistrationBehavior));
        }
        return defaultRegionBehaviorTypesDictionary;
    }
    catch (ActivationException)
    {
        return null;
    }
}

The other is responsible for registering any Ninject exception types considered to be root exceptions:

/// <summary>
/// Registers in the <see cref="IKernel"/> the <see cref="Type"/>
/// of the Exceptions that are not considered root exceptions
/// by the <see cref="ExceptionExtensions"/>.
/// </summary>
protected virtual void RegisterFrameworkExceptionTypes()
{
    ExceptionExtensions.RegisterFrameworkExceptionType(
        typeof(
            Microsoft.Practices.ServiceLocation.ActivationException
            ));
    ExceptionExtensions.RegisterFrameworkExceptionType(
        typeof(ActivationException));
}

There have also been changes in namespaces and interface names, all of which are detailed in this article. Hopefully by using the attached zip file, you will be able to sidestep these issues, and have a more painless transition to V2. I will try to get this code into the ninject-contrib project, once I find out how to do that.

Enjoy!

 

Shout it

Scrum Sprint Monitor configuration made much easier!

April 11th, 2009 Pedro Pombeiro No comments

I hope this will help drive the adoption of the Scrum Sprint Monitor. It certainly has been a pain point for people taking a look at the tool. Scrum Sprint Monitor has now full UI-based configuration:

image

Hope to see those Download numbers in CodePlex go up!

Categories: Scrum Sprint Monitor Tags:

Documentation for Scrum Sprint Monitor

April 9th, 2009 Pedro Pombeiro No comments

I finally got around to writing documentation for the Scrum Sprint Monitor, now at version 1.0.0.80. It includes details on setup, configuration and explanation of monitor items, all with lots of screen shots. Hopefully that will help prevent people giving up on the tool for lack of assistance.

Getting a consistent experience with design-time data in WPF (Part II)

March 18th, 2009 Pedro Pombeiro 3 comments

Now that we have our mock data showing up in Expression Blend, let’s get it working under Cider (the VS 2008 WPF designer). If you are really lucky, you might have hit all the right notes necessary to get it working the first time. If you fall under the other 99%, then follow the tips below:

Cider does not like the Window control for design-time data binding…

That’s right. This one actually took me the longest to figure out. It only hit me because I had one UserControl working correctly, so I started with a stripped down Window to determine the root cause. Turns out, if I change the Window to a UserControl, Cider is happy to do the data binding. So there are two ways you could get around this limitation:

  • Create an intermediate UserControl, and host that inside your Window; or
  • Add the DataContext to the root container element in your Window (e.g. a Grid). That seems to sidestep the Window data binding problem.

Put UserControl.DataContext after UserControl.Resources! … And,  declare the serviceProvider on the UserControl.Resources too!

I was getting erratic behavior hosting different controls from within the same project in my main Window. It ended up originating from a missing serviceProvider declaration. The hosted control is not able to find my App.xaml declarations, apparently. Therefore, if you host your UserControl Foo inside Control Bar, the designer will cough out the error "Could not create an instance of type ‘Foo" when you open Bar in the designer. Fortunately, you are able to define it in both App.xaml and on the UserControl, and it will not create problems in both Cider or Blend.

Sometimes, Cider calls IValueConverters with strange data

I have had Cider call a ValueConverter with a string, when I was expecting a business object instance. This caused the designer to catch an exception. The solution was to ignore unexpected types when in design mode (and this is actually suggested in a Microsoft Cide blog). Easy enough.

Now, for the final step…

Even though the previous steps should get the mock data showing up in Cider as well, you still have a problem: the design data will show up at run-time as well. There is an easy way to fix this:

public TeamMemberDataUserControl()
{
    InitializeComponent();

    if (!DesignerProperties.GetIsInDesignMode(this))
    {
        // Clear the design time data context
        ClearValue(DataContextProperty);
    }
}

You just clear the DataContext in the constructor of your control. That will execute at run-time, and reset the DataContext as if the XAML declaration wasn’t there.

As Eduardo pointed out to me, this has the side benefit of fixing another issue, as you will see in a bit. There are two different situations where you can see a control in design-mode. The simplest one is when you open the control file (let’s call it A.xaml) directly. The other one is when you open a control (B.xaml) which hosts A.xaml. In the latter situation, the designer will pass in the DataContext to the hosted control, but only if it does not already have a DataContext assigned already. Clearing the DataContext property in the constructor seems to do the trick. Eduardo also worked in a cleaner solution using attached properties, so he might blog a bit about that approach.

Wrap up

By following the steps in these two posts, you should be able to get your application showing design time data both in Expression Blend and Cider. You should not only be able to get that data in simple UserControls, but also Windows that nest other UserControls. If you would like to see the source code for an application that puts this into practice, take a look at the Scrum Sprint Monitor source code at CodePlex. Hope this is useful to you!

Technorati Tags: ,,,