Monday, September 12, 2011

Windows 7 Command Prompt Here

  1. Start > Run > regedit
  2. Navigate to HKEY_CLASSES_ROOT\Folder\Shell\
  3. Add key "MenuText"
  4. Set the default value to "Command Prompt Here"  (or whatever you want to call it)
  5. Add key "Command" under MenuText
  6. Set the default value to cmd.exe /K chdir /D "%1"
Enjoy!

Friday, May 27, 2011

How to: Configure the Windows Azure storage emulator to use SQL Server instead of SQL Express

By default, the Windows Azure storage emulator tries to use SQL Server Express for local storage.  However, you can easily configure it to use another instance of SQL Server.

Here's how (MSDN):


1.Click Start, point to All Programs, and then click Windows Azure SDK v1.3.
2.Right-click Windows Azure SDK Command Prompt, and then click Run as administrator.
3.In the Windows Azure SDK Command Prompt window, type the following command:

DSInit /sqlInstance:

Where is the name of the SQL Server instance.

You can also use the following command, which uses the default instance:
DSInit /sqlInstance:.

Friday, May 6, 2011

Silverlight: How to Bind a group of Radio Buttons on a DataGrid

If you’ve ever worked with the DataGrid in Silverlight, you may have noticed that there is no single control for binding a group of radio buttons to a single value.  Binding a group of radio buttons to a single property turns out to be far more difficult than I could have imagined. 

In this post, we're going to replace the Run Status ID with a group of radio buttons.
If you’re new to Silverlight, the first thing that you’ll notice is that there is no built in radio button group control.  Instead, you must use multiple RadioButton controls, and group them together using the GroupName property.  But before we discuss grouping, we need to put our radio buttons in DataGridTemplateColumn.


Next, add a StackPanel to the DataTemplate.

Next, add the first RadioButton to the stack panel.

As mentioned earlier, there is no single radio button group control.  Instead, you must bind the IsChecked property of each radio button to the underlying value property.


There’s two problems with this.  The first is that all radio buttons will be bound to the same property.  If we stop here, each radio buttons will try to set same bound property.  We’ll come back to this problem later.  The second problem is that unless the bound property is a boolean, the radio buttons won’t be able to bind to it correctly since IsChecked is a boolean.  To solve this problem, we must convert the source value to a boolean.  We can do this by creating and applying a value converter to the binding.  To create a value converter, create a class that implements IValueConverter.


The IValueConverter interface has two methods, Convert and ConvertBack.  When we apply the converter to our radio buttons, Silverlight will call the Convert method with the value of our binding source for each radio button.  It will also pass an optional parameter that we define.  We can use these two values to determine whether or not a radio button should be checked.  Remember that we’re binding our source value to the IsChecked property, so we need to return a boolean. 



This reads, if the binding source's value equals the parameter that we supply, return true (checked).  If not, return false (unchecked). 

To see this in action, we need apply our converter to our radio button's binding.  To make the converter accessible to our view, we must first make it a resource.


Next, apply the converter (by it’s key name above) and converter parameter to each radio button’s binding. 



Next, we need some way to group our radio buttons so that each data grid row will have it's own group of radio buttons.


Here, we're using the row's source entity key value, I5GenUnitsID, to make the group name unique for each row.  This value is formatted with 'Run{0}' so that we could add another column of radio buttons if we need to.

Continue adding a radio button for each RunStatusID.  If we’ve done everything correctly, we should be able to run our application and see that our radio buttons are correctly bound to the data source. 


But if you try to change one of the radio button groups, you get an error.  That's because we haven't implemented ConvertBack method yet.  We'll do that in a moment.

When you select a radio button, Silverlight calls the ConvertBack method of the converter.  It will pass the value of the radio button’s IsChecked property and, like the Convert method, will pass any ConverterParameter provided.  So what we need to do is return parameter if value equals true.


It shouldn’t surprise you that Silverlight call the ConvertBack method for the radio button being selected, but it may surprise you that it also calls this method for the radio button being unselected.  So what value should we return?  If we return null, Silverlight will attempt to set the run status ID to null.  It took me a lot of web searching to find the answer to this and I only found it mentioned once (here). 

When Silverlight calls the ConverBack method with a value of false (indicating that the radio button is unselected), simply return DependencyProperty.UnsetValue.  This apparently tells the framework not to set the binding source’s value.


Now, if we run our application again, we should see that we have successfully bound a group of radio buttons to the run status ID property.

Sunday, September 5, 2010

Using Extension Methods when Targeting .NET 2.0/3.0 in VS2010/2008

A while back, I wrote a DLL in VS2008 that contained business logic for a web page that I was building. The web site was also built in VS2008 and targeted .net 3.5. I made extensive use of LINQ and extension methods. A while later I had a need to use the same business logic in a SQL CLR assembly, targeting SQL Server 2005. Out of the box, SQL 2k5 only supports .net 2.0, but I found a hack to make my 3.5 DLL work in SQL 2k5. Over the next several months, the business needs changed and I had to change/extend the DLL to accommodate. Each time, I had to repeat my original hack which made the deployment very brittle, awkward and clumsy.

Last week, I began working on a new requirement that required me to change this DLL once again.  To make the deployment a little smoother this time, I considered targeting 2.0 instead of 3.5.  Of course, this would require that I rewrite my LINQ queries using classic .net constructs.  I wondered if this would also requirement to remove the extension methods that I had written.  I decided that I was willing to remove the LINQ queries, but removing the extension methods would have change the API, something that would have been far too painful. 

I did some reading and found that I should still be able to use extension methods when targeting .net 2.0, but when I tried I received the following compile error:
Error 1 Cannot define a new extension method because the compiler required type 'System.Runtime.CompilerServices.ExtensionAttribute' cannot be found. Are you missing a reference to System.Core.dll?
This seemed to contradict what I had read earlier.  I wasn't ready to give up yet, so I did some more searching and found a very simple solution.  Simply create an empty ExtensionAttribute in the System.Runtime.CompilerServices namespace.  That's it!?  That's too easy.  But it worked!
 

namespace System.Runtime.CompilerServices
{
    [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class | AttributeTargets.Assembly)]
    public sealed class ExtensionAttribute : Attribute
    {
    }
}

Tuesday, July 27, 2010

Using the DisplayFormatAttribute with the Silverlight DataGrid

While converting an MVC application to Silverlight, I was surprised to find that the DisplayFormatAttribute wasn't supported by the Silverlight DataGrid.

A common use for this would be to format dates and times. For example, let's say that your ViewModel has the following DateTime property that you want display the 24 hour time:

[DisplayFormat(DataFormatString = "{0:H:mm}")]
public DateTime TimeTag { get; set; }

After some web searching, I found a workaround posted on the Silverlight Toolkit issues tracker. The author suggested using the DataGrid's AutoGeneratingColumn event and reflection to apply an IValueConverter at run-time.

AutoGenerateColumn handler:

private void dg_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
{
    var senderType = (sender as DataGrid).ItemsSource.Cast<object>().FirstOrDefault().GetType();
    var format = senderType.GetProperty(e.PropertyName)
                           .GetCustomAttributes(typeof(DisplayFormatAttribute), true)
                           .Cast<DisplayFormatAttribute>().FirstOrDefault();
    (e.Column as DataGridTextColumn).Binding.Converter 
           = format != null 
                    ? new DisplayFormatConverte(format.DataFormatString)
                    : null;
}

IValueConverter implementation:
public class DisplayFormatConverter : IValueConverter
{
    private string _format;

    public DisplayFormatConverter(string format)
    {
        _format = format;
    }

    #region IValueConverter Members

    public object Convert(object value, Type targetType, object parameter,
                          CultureInfo culture)
    {
        return String.Format(_format, value);
    }

    public object ConvertBack(object value, Type targetType,
                              object parameter, CultureInfo culture)
    {
        try
        {

            if (targetType == typeof(DateTime))
            {
                if (value is string)
                    return DateTime.Parse(value.ToString());
                return System.Convert.ToDateTime(value);
            }
            if (targetType == typeof(decimal))
            {
                if (value is string)
                    return decimal.Parse(value.ToString());
                return System.Convert.ToDecimal(value);
            }
            // TODO: Add additional parsers/converters here
        }
        catch (FormatException)
        {
        }
        return value;
    }

    #endregion
}
Suggestions/Comments?

Sunday, July 4, 2010

Guidelines with Tab indentation

Guidelines do not work correctly when code is indented using tabs instead of spaces. The guideline appears at the number of characters (tabs) instead of where the cursor is located.

Microsoft Connect Bug

Wednesday, June 30, 2010

MCTS 70-516 Passed!!

I found out this morning that I passed the beta MCTS 70-516 exam, Accessing Data with ADO.net! This came as somewhat of a surprise because I can think of a couple questions that probably got wrong. The ones that you can remember are often the tip of the iceberg. Either they threw out the questions that I got wrong, or I had enough right to pass the exam.

In any case, I am now a certified technical specialist in Data Access with ADO.net (4.0)!