Tijmen 02:22, 28 August 2009

I've been working a lot with stored procedures and the Linq to Sql designer. One of the annoyances is that all of a sudden when you drop the nth sproc to the designer it would not allow creating the codebehind anymore. It'll then throw the most usefull message:

"The operation could not be completed"

There's an easy fix however, open a Visual Studio command prompt and hit

"devenv /resetskippkg"

 

Works like a charm.

Tijmen 08:50, 17 August 2009
I am sure I ran into this before, but it took me some time to figure out yet again. Something like that always shouts "blog it" to me, so here goes. I installed a ClickOnce application, that neatly installed itself and placed an appropriate shortcut in my start menu. I then fired up Launchy, rebuilt the catalog and started looking for the new app... which didn't show up.
Searching through the start menu using standard Windows functionality of win-key + start typing (which admittedly got a lot better and snappier in Windows 7, though nowhere near powerful enough for us pro-keystrokers) resulted in the correct shortcut, though.
Long story short: the ClickOnce shortcuts have an extension *.appref-ms. By adding that file type to the various directories that Launchy indexes (right click, options, catalog tab) and rebuilding the catalog, the shortcuts show up in Launchy as well. By the way, on my Windows 7 machine, the start menu shortcuts are in the following folders (I am not sure if Launchy sets those correctly from the start):
  • c:\ProgramData\Microsoft\Windows\Start Menu
  • c:\users\<username>\AppData\Roaming\Microsoft\Windows\Start Menu
Tijmen 03:10, 8 August 2009

At my current project we needed a quick sort of throw away app that was going to be used by a small group of people. Without going into much details the app basically is a planning and analysis module for the allocation of employees to divisions.

Since development speed is crucial we decided to work with Linq2sql and winforms. No need for all sorts of layers; just get it done.

 

We needed to fill a combobox with values. This should be trivial, but was a bit more trouble than expected. I ended up using the excellent description found here. Basically all you need to do is:

var comboBox = new ComboBox();
var choices = new Dictionary<string, string>();
choices["A"] = "Arthur";
choices["F"] = "Ford";
choices["T"] = "Trillian";
choices["Z"] = "Zaphod";
comboBox.DataSource = new BindingSource(choices, null);
comboBox.DisplayMember = "Value";
comboBox.ValueMember = "Key"; 

 

Notice the clever use of new BindingSource(choices, null);

 

Nothing complex here, but this is static and I wanted to get the values from the db. Next to that it would be nice if we could have some sort of generic function that could take a type of TEntity (table) and some hints to which properties in TEntity it needed as Key and Value.

I ended up with this:

public interface IComboBoxHelper
{
    void SetComboBoxContent<TEntity, TKey, TValue>(
            Func<TEntity, TKey> key,
            Func<TEntity, TValue> value, 
            ComboBox comboBox)
        where TEntity : class;
}

Usage becomes pretty straightforward: register the IComboBoxHelper and it's implementation to the Dependency injection container. Add a constructor dependency and use the helper variable:

comboBoxHelper.SetComboBoxContent<Divisie, int, string>(s=> s.Divisie_PK, s=> s.Divisienaam, comboBox);

The implementation of the IComboBoxHelper takes a datacontext and is responsible for looking up the required entity.

Let's have a look at the actual implementation:

public class ComboBoxHelper : IComboBoxHelper
{
    readonly HRDataContext dataContext;

    public ComboBoxHelper(HRDataContext dataContext)
    {
        this.dataContext = dataContext;
    }
   
    public void SetComboBoxContent<TEntity, TKey, TValue>(
            Func<TEntity, TKey> key,
            Func<TEntity, TValue> value, 
            ComboBox comboBox)
        where TEntity : class
    {
        Dictionary<TKey, TValue> dictionary = new Dictionary<TKey, TValue>();

        IQueryable<TEntity> entities = dataContext.GetTable<TEntity>().Select(s => s);
        entities.ForEach(s => dictionary.Add(key(s), value(s)));
        var source = new BindingSource(dictionary, null);
        comboBox.DataSource = source;
        comboBox.DisplayMember = "Value";
        comboBox.ValueMember = "Key";
    }
}

Nothing too complicated, but the use of Func's to get to the properties in the required Entity is pretty nice.

Technorati Tags: ,,