Month: February 2010

KeyboardShortcuts

I’ve put together a couple of scripts, poached from the interWebs, that will give those VS.NET keyboard ninjas some more shortcut-fu. Rather than relying on different, incomplete cheatsheets for each of your plugin’s keyboard shortcuts, this macro will find all of your current shortcuts and present them in a single table.

From VS.NET 2008 open the Macros IDE:
Tools > Macros > Macros IDE

Once in the Macros IDE, create a new Module:
Project Explorer > My Macros (context menu) > Add > Add Module ("KeyboardShortcuts")

Copy the following over the file’s contents:

Imports EnvDTE
Imports System.Diagnostics

Public Module KeyboardShortcuts

    Sub ListKeyboardShortcuts()
        Dim i As Integer
        Dim j As Integer
        Dim pane As OutputWindowPane = GetOutputWindowPane("Commands")
        Dim keys As System.Array

        pane.Clear()
        pane.OutputString("<font face=arial>")
        pane.OutputString("<table border=1 cellspacing=0 cellpadding=2 bgcolor=f0f0ff>" + Chr(10))
        pane.OutputString("<tr><th colspan=2 bgcolor=d0d0e0>Keyboard Mappings</th></tr>" + Chr(10))
        pane.OutputString("<tr><th bgcolor=e0e0f0>Action</th>")
        pane.OutputString("<th bgcolor=e0e0f0>Key</th></tr>" + Chr(10))

        For i = 1 To DTE.Commands.Count
            keys = DTE.Commands.Item(i).Bindings
            If keys.Length > 0 Then
                pane.OutputString("<tr>")

                'DTE.Commands.Item(i).Name() is sometimes blank.
                'We will print an m-dash in this case, as printing a blank table cell is visually
                'misleading, as such a cell has no borders, making it appear to be attached to
                'another cell.
                If DTE.Commands.Item(i).Name() <> "" Then
                    pane.OutputString("<td valign=top>" + DTE.Commands.Item(i).Name())
                Else
                    pane.OutputString("<td><center>&mdash;</center>")
                End If

                pane.OutputString("</td><td>")
                For j = 0 To keys.Length - 1
                    If j > 0 Then
                        pane.OutputString("<br/>")
                    End If
                    pane.OutputString(keys(j))
                Next
                pane.OutputString("</td></tr>" + Chr(10))
            End If
        Next

        pane.OutputString("</table></font>")

    End Sub

End Module

You’ll notice the error squiggle under the GetOutputWindowPane() call. We have to add that Utility in (it used to come with the Samples):
Project Explorer > My Macros (context menu) > Add > Add Module ("Utilities")

Imports System
Imports EnvDTE
Imports EnvDTE80
Imports EnvDTE90
Imports System.Diagnostics

Public Module Utilities

    ' This function retrieves the output window pane
    Function GetOutputWindowPane(ByVal Name As String, Optional ByVal show As Boolean = True) As OutputWindowPane
        Dim window As Window
        Dim outputWindow As OutputWindow
        Dim outputWindowPane As OutputWindowPane

        window = DTE.Windows.Item(EnvDTE.Constants.vsWindowKindOutput)
        If show Then window.Visible = True
        outputWindow = window.Object
        Try
            outputWindowPane = outputWindow.OutputWindowPanes.Item(Name)
        Catch e As System.Exception
            outputWindowPane = outputWindow.OutputWindowPanes.Add(Name)
        End Try
        outputWindowPane.Activate()
        Return outputWindowPane
    End Function

End Module

To execute the macro go back to VS.NET:
Tools > Macros > Macros Explorer > ListKeyboardShortcuts (context menu) > Run

Yes, the output goes to the Output view and you have to cut-and-paste it into a .html but hey, if you want it to do more, update the script. 🙂 HTH

How to fit Scrum into a fixed contract?

We can’t bid on contracts on the basis of doing Scrum as Sales believe they won’t win any contracts. We’re doing Scrum, however, because we believe it increases our changes of delivering. So we’re doing Stealth Scrum in that we won’t explicitly tell the customers about it. We’ve identified a number of ways of creating a contract that can work with Scrum and will be acceptable to our customers.

Time and Materials (T&M) in the terms, perhaps around the installation, can allow for some incremental releases. The bulk of the contract can still be fixed price and the T&M can be budgeted. That way the customer can get sign-off on the budget and we have some room in which to be Agile.

Release points in the contract are so the customer gets early insight into the product. They’ll certainly have feedback and then the functionality may be renegotiated. Done on a capability in, capability out basis the budget need not be changed (which will save a lot of headaches for them as they don’t then need to go and talk to Accounts). If we release Minimum Marketable Features (MMF) early the customer has plenty of opportunity to get involved.

In the contract we talk about how we are going to work with the customer. If regular access to a customer representative can be negotiated then they can be regularly reviewing progress, both catching mis-steps early and also preventing the Team doing work that won’t be accepted or isn’t required. The better communication with the customer will improve the trust between us and them.

Change Requests (CRs) can be created that the customer may, or may not, pay for. Even though the contract will have the functional specification stapled onto the back it’s understood that change must be managed. Stating goals for the project will hopefully guide negotiations around scope creep. CRs are a tricky area as it can damage the trust between ourselves and our customer if not handled sensitively.

We do a Design Study before software construction commences. The customer is guided as to what a Design Study constitutes so that what they expect from it matches closely the coarse-grained estimates you’d expect at this stage. This will minimise the normal contract practices of cost padding and caveats.

Scrum handles what project risk it can through reprioritisation of the product backlog, raising riskier workitems to the top. This needn’t be raised to the customer unless we now suspect something is going all the way to the freezer [front-burner, back-burner, fridge, freezer]. Other project risk has to be addressed through standard project management techniques.

Scrum can manage risk through the trust that is built up between the customer and the team. The customer accepts that the team will do their absolute best to deliver business value as fast as they can and pays for the time required to make the delivery. The team does everything in their power to be transparent so that the customer knows exactly what to expect and can be comfortable that they are getting value. This trust can be difficult to achieve when attempting Stealth Scrum.

Additional Reading.
10 Contracts for your next Agile Software Project
NoFixed.org