Team Foundation 2010: Associate work item with changeset AFTER check in.

Today I was struggling associating a work item with a changeset after a check in. There is however no options for this in the UI. Or is there? Let’s check:

Cannot edit work items from changeset window

Ok, so not through the changeset UI.

Let’s check the command line.

c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC>tf changeset /?
TF - Team Foundation Version Control Tool, Version 10.0.30319.1
Copyright (c) Microsoft Corporation.  All rights reserved.

Displays information about a changeset and lets you change the associated
attributes, such as comments and check-in notes.

tf changeset [/comment:("comment"|@commentfile)]
             [/notes:("NoteFieldName"="NoteFieldValue"|@notefile)] [/noprompt]
             [/collection:TeamProjectCollectionUrl]
             [changesetnumber | /latest] [/login:username,[password]]

(emphasis mine).

So not through the command line. Now what? Let’s think: we want to associate a changeset with a work item. Why not look the other way around?

After the successful commit remember the changeset # (in our example 25464), go to the work item you want to associate the changeset to.

Right bottom you’ll see a tab called ‘Links’ (1), click it, and then click the ‘Link to’ (2) button.

Associate work item with changeset

In the next window, select ‘Changeset’ (1) and enter the number in the box (2). Hit  ‘OK’ (3).

Associate part II

After that hit ‘CTR+S’ to save your work item.

After that go back to your changeset:

It's there!

It works!

Have a good one!

-Kristof

Silverlight 4: Bug in TabControl.TabStripPlacement = Dock.Left and OnApplyTemplate

At work I ran into a bug with the Silverlight TabControl, more specifically when setting the TabStripPlacement to Dock.Left and hiding one of the TabItems in the parent’s OnApplyTemplate.

The way to get to this bug is quite specific. For example, you can’t do it when you’re using a UserControl, since in that kind of class OnApplyTemplate is never called.

You need to build a class which inherits from Control.

public class TabControlTest : Control

Then we have the style of this particular class:

<Style TargetType="TabControlTest:TabControlTest"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="TabControlTest:TabControlTest"> <Grid x:Name="LayoutRoot" Background="White"> <Grid.RowDefinitions> <RowDefinition Height="*" /> <RowDefinition Height="38" /> </Grid.RowDefinitions> <sdk:TabControl TabStripPlacement="{TemplateBinding TabStripPlacement}" Grid.Row="0"> <sdk:TabItem Header="First"> <sdk:TabItem.Content> <TextBlock Text="A" /> </sdk:TabItem.Content> </sdk:TabItem> <sdk:TabItem Header="Second" x:Name="middleTabItem"> <sdk:TabItem.Content> <TextBlock Text="B" /> </sdk:TabItem.Content> </sdk:TabItem> <sdk:TabItem Header="Last"> <sdk:TabItem.Content> <TextBlock Text="C" /> </sdk:TabItem.Content> </sdk:TabItem> </sdk:TabControl> <Button HorizontalAlignment="Center" Grid.Row="1" Content="{TemplateBinding ShowOrHide}" Command="{TemplateBinding ShowOrHideCommand}" /> </Grid> </ControlTemplate> </Setter.Value> </Setter> </Style>

As you can see I’ve named the middle TabItem (“middleTabItem”) so I can retrieve it in the OnApplyTemplate:

public override void OnApplyTemplate()
{
    this._middleTabItem = (TabItem) this.GetTemplateChild("middleTabItem");
    this._middleTabItem.Visibility = Visibility.Collapsed;

    base.OnApplyTemplate();
}

Now if the following 2 conditions are matched:

  1. TabStripPlacement is set to Dock.Left (it doesn’t happen on ‘Top’)
  2. We set the Visibility of the said TabItem to Collapsed in the OnApplyTemplate of the surrounding Control

Then we cannot make the TabItem Visible anymore.

To show or hide I use the following code:

this.ShowOrHideCommand = new Command(() =>
                                         {
                                            this.ShowOrHideText = string.Format(SwitchTo, this._middleTabItem.Visibility);
                                            this._middleTabItem.Visibility = this._middleTabItem.Visibility == Visibility.Visible ? Visibility.Collapsed : Visibility.Visible;
                                         });

The solution to this is to call the OnApplyTemplate of the TabControl itself so that it recalculates it’s children’s location (or something, I’m not sure):

Give the TabControl a name, fetch it in OnApplyTemplate of your Control:

<sdk:TabControl TabStripPlacement="{TemplateBinding TabStripPlacement}" x:Name="TabControl" Grid.Row="0">
public override void OnApplyTemplate()
{
    this._middleTabItem = (TabItem) this.GetTemplateChild("middleTabItem");
    this._middleTabItem.Visibility = Visibility.Collapsed;
    this._tabControl = (TabControl) this.GetTemplateChild("TabControl");
    base.OnApplyTemplate();
}

And call the _tabControl’s OnApplyTemplate after switching the Visibility to Visible:

this.ShowOrHideCommand = new Command(() =>
                                         {
                                            this.ShowOrHideText = string.Format(SwitchTo, this._middleTabItem.Visibility);
                                            this._middleTabItem.Visibility = this._middleTabItem.Visibility == Visibility.Visible ? Visibility.Collapsed : Visibility.Visible;
                                            this._tabControl.OnApplyTemplate();
                                         });

This will make the UI respond correctly. For your convenience I’ve added the SL project, and you can download it here.

Visual Studio 2010 SP1: DebuggerTypeProxy works again! *yay*

A while ago I bumped into a bug in Visual Studio 2010 + Silverlight 4.

While working with a List / Dictionary / … it didn’t show the items in the list, instead it showed the normal ‘raw view’:

No debug view

As you can see, there was no view to see the items.

What you would expect to see is this:

DebugView!

I reported the bug (many others did too!). The problem was that it was fixed in SL3, but not ported to SL4.

Now it’s fixed! This makes my work a lot easier. When we get SP1 @ work too that is!

Cheers!

Dictionary<TKey, TValue> finding key: try/catch vs TryGetValue

Today I saw some code where the developer accessed a dictionary like this:

  1. void Foo(int keyToFindInDictionary)
  2. {
  3.     Dictionary<int, string> dictionary = new Dictionary<int, string>();
  4.  
  5.     try
  6.     {
  7.         DoSomethingWithTheResult(dictionary[keyToFindInDictionary]);
  8.     }
  9.     catch (KeyNotFoundException)
  10.     {
  11.         // fallback
  12.     }
  13. }
  14.  
  15. private void DoSomethingWithTheResult(string s)
  16. {
  17.     // do something
  18. }

As you can see he catches the exception to handle the fact that the given key was not found in the dictionary.

I told him that there was a better way, i.e. Dictionary<TKey, TValue>.TryGetValue.

And then the curious part of me started thinking, how much better is it? Is it faster? Slower?

So I wrote the following small piece of code to test my statement that TryGetValue is better than catching the KeyNotFoundException.

  1. namespace DictionaryTryGetValueVersusException
  2. {
  3.     using System;
  4.     using System.Collections.Generic;
  5.     using System.Diagnostics;
  6.  
  7.     internal class Program
  8.     {
  9.         private static void Main()
  10.         {
  11.             // create a dictionary with some values
  12.             Dictionary<string, string> dictionary = new Dictionary<string, string>();
  13.  
  14.             // add 10,000 items
  15.             for (int i = 0; i < 10000; i++)
  16.             {
  17.                 if (i == 5000)
  18.                 {
  19.                     // skip
  20.                     continue;
  21.                 }
  22.  
  23.                 dictionary.Add(string.Format("Key{0}", i), string.Format("Value{0}", i));
  24.             }
  25.  
  26.             Stopwatch stopwatch = new Stopwatch();
  27.  
  28.             stopwatch.Start();
  29.  
  30.             const string keyToFindInDictionary = "Key5000";
  31.  
  32.             for (int i = 0; i < 10000; i++)
  33.             {
  34.                 // 5000 does not exist
  35.                 try
  36.                 {
  37.                     // execute a method on the variable, so that he compiler doesn't optimize it.
  38.                     dictionary[keyToFindInDictionary];
  39.                 }
  40.                 catch (Exception)
  41.                 {
  42.                     // ignore
  43.                 }
  44.             }
  45.  
  46.             stopwatch.Stop();
  47.             Console.WriteLine("Dictionary lookup with try/catch took: {0}", stopwatch.ElapsedTicks);
  48.  
  49.             stopwatch.Restart();
  50.  
  51.             for (int i = 0; i < 10000; i++)
  52.             {
  53.                 string notFound;
  54.                 // 5000 does not exist
  55.                 dictionary.TryGetValue(keyToFindInDictionary, out notFound);
  56.             }
  57.  
  58.             stopwatch.Stop();
  59.             Console.WriteLine("Dictionary lookup with TryGetValue took: {0}", stopwatch.ElapsedTicks);
  60.  
  61.             Console.WriteLine("Done, press enter to exit");
  62.             Console.ReadLine();
  63.         }
  64.     }
  65. }

As you can see we add 10,000 items to the dictionary, skipping the 5000th item, and then we do a lookup in the dictionary, 10,000 times, on the key that doesn’t exist, to measure the performance difference between the 2 previously discussed methods.

To run this test I did a Release Build in Visual Studio 2010, .NET 4.0, Any CPU, and this is the result:

Results

Dictionary lookup with try/catch took: 1069625
Dictionary lookup with TryGetValue took: 864
Done, press enter to exit

As you can see there is a HUGE difference. The TryGetValue-way was about 1237 faster!

Exception throwing is very heavy! Don’t forget that. It doesn’t mean that you need to program without exceptions, but when you EXPECT that a Key is not present in a given dictionary, don’t use the exception. Use the TryGetValue. If you always expect it to be there then it’s normal to catch the exception, because it’s exceptional that the key was not found.

PS: I tried the code again by skipping the 9999th item, and the results were about the same, take or leave a few milliseconds. So searching in the dictionary is very performant (close to O(1), as written in the Remarks section on this page.)

Stopping Casini before (re)building website in Visual Studio revisited

This is an update of an older post of mine on stopping Casini.

The code posted in the previous article (yes, read it!) only stops Webdev.Webserver, which is included in Microsoft Visual Studio 2010.

Now the problem is that when you’re using Blend and accidently run the app from there (which I hate, I’d prefer it to switch to Visual Studio).

This shortcut will allow you to quickly kill the webdev server of Blend (and that of Visual Studio too). So just keep it as a shortcut.

C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe Stop-Process -Name @('WebDev.WebServer*', 'Microsoft.Expression.Web*')

Good luck :)

Enum dependency property caveat

Hi all,

A while ago I was creating a custom control in Silverlight with an enum Dependency property.

It looked like this:

  1. public partial class SomeCustomControl
  2. {
  3.     public static readonly DependencyProperty OnOrOffDependencyProperty = DependencyProperty.Register("OnOrOff", typeof (OnOff), typeof (SomeCustomControl), new PropertyMetadata(-1, OnPropertyChangedCallback));
  4.  
  5.     public SomeCustomControl()
  6.     {
  7.         this.InitializeComponent();
  8.     }
  9.  
  10.     public OnOff OnOrOff
  11.     {
  12.         get
  13.         {
  14.             return (OnOff) this.GetValue(OnOrOffDependencyProperty);
  15.         }
  16.         set
  17.         {
  18.             this.SetValue(OnOrOffDependencyProperty, value);
  19.         }
  20.     }
  21.  
  22.     private static void OnPropertyChangedCallback(DependencyObject o, DependencyPropertyChangedEventArgs e)
  23.     {
  24.         SomeCustomControl instance = (SomeCustomControl) o;
  25.  
  26.         instance.UpdateBackgroundColor((OnOff) e.NewValue);
  27.     }
  28.  
  29.     private void UpdateBackgroundColor(OnOff newValue)
  30.     {
  31.         switch (newValue)
  32.         {
  33.             case OnOff.On:
  34.                 this.Rectangle.Fill = new SolidColorBrush(Colors.Green);
  35.                 break;
  36.             case OnOff.Off:
  37.                 this.Rectangle.Fill = new SolidColorBrush(Colors.Red);
  38.                 break;
  39.         }
  40.     }
  41. }

The enum itself was quite simple:

  1. public enum OnOff
  2. {
  3.     On,
  4.     Off
  5. }

The control just changes background color when you set the enum to On (green), or Off (red). Very simple.

The problem is that the dependency property will take the enum member with number 0 as default, OnOff.On that is. And when setting the value in XAML (or code for that matter) will not update the property backing the dependency property:

Where is the green color? :(

The code to render this is found here:

  1. <EnumProblem:SomeCustomControl OnOrOff="On"
  2.                                        Grid.Row="1">
  3.         </EnumProblem:SomeCustomControl>
  4.         <EnumProblem:SomeCustomControl OnOrOff="Off"
  5.                                        Grid.Row="1"
  6.                                        Grid.Column="1">

As you can see the left one is NOT green.

This is because the default is OnOff.On (value 0), and setting it (again) to On doesn’t trigger the execution of OnPropertyChangedCallback.

We can solve this (of course, otherwise what would be the point of writing this? :P )

The first solution you might think about is setting the default value of the Dependency Property’s default value. Maybe –1 for example, so that at least the engine can detect a change.

  1. public static readonly DependencyProperty OnOrOffDependencyProperty = DependencyProperty.Register("OnOrOff", typeof (OnOff), typeof (SomeCustomControl), new PropertyMetadata(-1, OnPropertyChangedCallback));

Running the app like this will cause an exception, since it cannot convert the –1 to the OnOff enum.

Error when PropertyMetaData.Default = -1

The other solution is setting the value of the first member to a positive value, which makes the code work:

  1. public enum OnOff
  2. {
  3.     On = 1,
  4.     Off
  5. }

It works!

Now you might think: What’s the difference, the first time it tries to convert –1 to OnOff, and the second time it tried to convert 0 to OnOff, and it both cases it the value doesn’t exist in the enum.

The reason here is that you can have an enum that starts at 1, but you can still set create an instance of that enum with a value of 0.

Enum to 0

But creating the enum with a value of –1 doesn’t work:

-1 doesn't work

This is why setting –1 to the default value of the dependency property doesn’t work (unless you of course have a –1 value in the enum!)

If you want the source, and you know a good place to upload it, please mail me :)

Stopping Casini before (re)building website in Visual Studio

Hi ya’ll,

I sometimes use Casini to debug local web applications. Casini is easy to configure, no need to create a virtual directory, it’s gone after you close Visual Studio so it’s easy.

The problem is that sometimes when changing some code, Casini’s caches aren’t cleared. So you get a stale version of your webpage (or Silverlight or …).

While playing with Powershell I found a little gem called Stop-Process. It even accepts wildcards! Which is nice, since there are 2 WebDev.Webservers. One for .NET 2.0 and one for .NET 4.0.

How can we link this to Visual Studio? Easy. Go to your web project and double-click properties:

Double-click properties

Then go to Build Events, and enter the following text in the Pre-Build event command line (as shown on the picture):

powershell Stop-Process -name webdev.webserver*

Build Events

Next time when you rebuild, Casini will be stopped, and you will always start from a clean page :)

Enjoy.

-Kristof

Visual Studio 2010 PowerTools

Hi All,

Since I’ve installed Visual Studio 2010 PowerTools I’ve had the following problem:

Entering shift+enter didn’t break the line anymore.

This is because of the autocomplete braces function of the PowerTools.

You can disable this function by clicking Options in the Tools Menu:

Tools > Options

And then click ‘Productivity Power Tools’ on the left:

Productivity Power Tools options

In that window set ‘Automatic Brace Completion’ to ‘Off’.

Now restart your Visual Studio 2010 (Important!)

Unfortunately this doesn’t restore the shortcut in the keyboard settings of Visual Studio 2010.

To fix this go to your keyboard settings in Visual Studio 2010:

Edit.BreakLine

And enter this string in the search box: ‘Edit.BreakLine’ (without the quotes).

As you can see only ‘Enter’ is mapped to BreakLine.

Now set focus to the ‘Press shortcut keys’ textbox and press Shift+Enter. And then hit Assign.

This is the end result:

Set Shift+Enter to Edit.BreakLine

There we go :)

Take it easy,

Kristof

Windows Phone 7 TextBox, binding and ApplicationButton

Consider a Windows Phone 7 application with a textbox and an ApplicationButton.

TextBox and ApplicationButton

UI:

  1. <Canvas x:Name="ContentGrid" Grid.Row="1" Height="545" Width="480">
  2.     <TextBlock Text="Enter text here" Canvas.Left="6" Canvas.Top="187" />
  3.     <TextBox x:Name="myTextBox" Text="{Binding Test, Mode=TwoWay}" Height="69" Width="480" Canvas.Left="0" Canvas.Top="209" />
  4. </Canvas>

Backend:

  1. namespace WindowsPhoneApplication1
  2. {
  3.     using System;
  4.     using System.ComponentModel;
  5.     using System.Windows.Controls;
  6.     using Microsoft.Phone.Controls;
  7.  
  8.     public partial class MainPage : PhoneApplicationPage, INotifyPropertyChanged
  9.     {
  10.         private string _test;
  11.         // Constructor
  12.         public MainPage()
  13.         {
  14.             this.InitializeComponent();
  15.  
  16.             this.DataContext = this;
  17.         }
  18.  
  19.         public string Test
  20.         {
  21.             get
  22.             {
  23.                 return this._test;
  24.             }
  25.             set
  26.             {
  27.                 if (value != this._test)
  28.                 {
  29.                     this._test = value;
  30.                     this.PropertyChanged(this, new PropertyChangedEventArgs("Test"));
  31.                 }
  32.             }
  33.         }
  34.  
  35.         #region INotifyPropertyChanged Members
  36.  
  37.         public event PropertyChangedEventHandler PropertyChanged;
  38.  
  39.         #endregion
  40.  
  41.     }
  42. }

The textbox is bound to a property on the backend (two way binding) and when you click the bottom button the text is saved/send/encrypted/whatever.

Now the problem is that clicking the button doesn’t do a UI –> source binding update as it would do with a normal button.

Testing the app

I enter the text ‘test’ on the TextBlock and IMMIDIATLY click the ApplicationButton. I don’t do anything else. This is a common user practice, he changes something and clicks the save/send/whatsoever button.

This is the result:

Visual Studio 2010 Watch 1

Check the Watch 1. As you can see the value is still null. The value is not sent to the _test value. How do we solve this?

You can add the following line to the click event handler:

  1. this.myTextBox.GetBindingExpression(TextBox.TextProperty).UpdateSource();

So the result will look like this:

  1. private void AppbarButton1Click(object sender, EventArgs e)
  2. {
  3.     this.myTextBox.GetBindingExpression(TextBox.TextProperty).UpdateSource();
  4.  
  5.     // handle save/send/encrypt/whatever here
  6. }

There are 3 downsides I think:

  1. You need to name your TextBlock which (I think) unnecessarily clutters your scope with otherwise unused variables (that’s why we use bindings too!)
  2. Your UI and ViewModel (in my case) aren’t decoupled 100% anymore. In Windows Phone 7 this is no issue though, since WP7 has no ICommand and I have to couply my UI and ViewModel anyway :)
  3. You need to remember to write this line! Which can be quite cumbersome with a lot of application buttons.

And items in a ApplicationBar.MenuItems (ApplicationBarMenuItem) have the same problem. The UI doesn’t push the update to the ViewModel.

I hope this will be fixed in the final version, and I will post this to Microsoft Connect. If anybody has a better solution please feel free to share it.