WinForms ListView DoubleClick Event for Empty Lists

The WinForms ListView control fires double click events only if the user clicked on a selected item. This is also documented on the MSDN site: “The mouse pointer must be over a child object (TreeNode or ListViewItem).” (Control.DoubleClick Event).

Sometimes it is useful to perform actions on double click events for empty ListView controls, too.

To achieve this you have to implement a custom ListView control which inherits from the original WinForms ListView control:

using System;
using System.Security.Permissions;
using System.Windows.Forms;

internal class CustomListView : ListView
{
    private const int WM_LBUTTONDBLCLK = 515;

    private bool doubleClickFired;

    protected override void OnDoubleClick(EventArgs e)
    {
        base.OnDoubleClick(e);

        this.doubleClickFired = true;
    }

    [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
    protected override void WndProc(ref Message m)
    {
        this.doubleClickFired = false;

        base.WndProc(ref m);

        if (m.Msg == WM_LBUTTONDBLCLK && !this.doubleClickFired)
        {
            this.OnDoubleClick(EventArgs.Empty);
        }
    }
}

This custom control checks whether a double click event was triggered for double clicks of the left mouse button on the control. If this is not the case, it triggers a double click event “manually”.

Posted in .NET, UI | Tagged , , , | Leave a comment

Planning Center Online – Custom Plan Reports in Landscape Orientation

Planning Center Online allows to create custom reports (i.e. print templates) for plans: http://help.planningcenteronline.com/s/planning-center/m/planning-center/l/49253-custom-reports-wiki

To create reports with landscape orientation it is import that style tags have no type attribute. Otherwise the generated PDF files are always (independent of selected print options) in portrait orientation with large margins.

<style>

But not

<style type="text/css">

This is probably due to a bug in the used PDF generator (“Prince”, currently used version is 7.1).

Posted in Allgemein, PCO | Tagged , | Leave a comment

How to configure ConnectionStrings in web.config per developer/user

One thing Martin Fowler states in his article about Evolutionary Database Design is that every developer needs to have its own database instance.

For .NET Windows client projects you can simply change the ConnectionStrings configuration in the App.config file inside the bin directory. But for web/ASP.NET projects this is not possible, because the root directory for debugging the project is the project directory itself (being under source control). I.e. you would have to checkout the web.config file from source control and edit it. This itself is not such a problem, but you always have to watch out to not check the changed web.config file into source control.

The Solution

A solution to make this work is to split the web.config configuration into multiple files and extend the build process by editing the project file of the web project to create a configuration file which is not in source control and therefore can be customized per developer.

1. Split the configuration

Replace the connectionStrings configuration in your web.config file with the following line:

  <connectionStrings configSource="connectionStrings.config" />

2. Create a default configuration

Create a new configuration file “connectionStrings.default.config” with your configured ConnectionStrings (example):

<?xml version="1.0" encoding="utf-8"?>
<connectionStrings>
    <add 
      name="MyDbConnection" 
      connectionString="Data Source=(local)\SQLEXPRESS;Initial Catalog=MyAppDb;User ID=myapp;Password=123pw" />
</connectionStrings>

3. Extend the build process

Edit the project file and include a new target “BeforeBuild” (at the bottom of the file, but inside the “project” node):

<Target Name="BeforeBuild">
  <Copy 
      Condition="!Exists('connectionStrings.config')" 
      SourceFiles="connectionStrings.default.config" 
      DestinationFiles="connectionStrings.config" />
</Target>

This extends the build process with a new step which checks whether the file “connectionStrings.config” exists and (if not) copies the file “connectionStrings.default.config” to “connectionStrings.config“. When you want to change a ConnectionString in your local development environment you can simply edit the file “connectionStrings.config” and adjust it to your environment.

4. Add a transformation for publishing

For publishing/deploying your project you can create a web.config transformation which “inlines” the ConnectionStrings again:

<?xml version="1.0" encoding="utf-8"?>

<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
  <connectionStrings xdt:Transform="Replace">
    <add 
      name="MyDbConnection" 
      connectionString="Data Source=(local)\SQLEXPRESS;Initial Catalog=MyAppDb;User ID=myapp;Password=123pw" />
  </connectionStrings>
</configuration>

Summary

Summing it up, the solution consists of the following parts

  • An outsourced ConnectionString configuration not under source control.
  • A default ConnectionString configuration under source control.
  • A build step ensuring a ConnectionString configuration exists at the expected path.
  • (Optional) A web.config transformation for cleaning everything up on publishing/deploying the project.
Posted in .NET, ASP.NET | Tagged , , , | Leave a comment

Reporting Exceptions from ELMAH to Graphite and StatsD

On one project we use Graphite and StatsD to monitor some webserver and performance parameters of the site and ELMAH to catch all unhandled exceptions. Wouldn’t it be cool to also see the occurrence of exceptions captured by ELMAH in our Graphite graphs?

For this purpose I extended my library of Graphite “tools” by a Graphite.Elmah project.

ELMAH is designed to support only on backend for logging errors. This is usually configured to be some kind of database backend to store exception details for later access. Therefore Graphite.Elmah hooks into ELMAH using a custom error filter, to report exceptions to Graphite or StatsD.

You can configure ELMAH in your project to use this error filter with the following configuration snipped:

<errorFilter>
  <test
      xmlns:my="http://schemas.microsoft.com/clr/nsassem/Graphite/Graphite.Elmah">
    <my:log />
  </test>
</errorFilter>

Graphite.Elmah itself needs to be configured with the following settings:

<graphite.elmah
    key="elmah_errors"
    type="counter"
    target="statsd" />

You can set a metric key, a metric type and a target for the metrics (either “statsd” or “graphite”). The complete configuration for your web.config file is also included in the respective readme for reference: Graphite.Elmah web.config

Graphite.Elmah was build upon the Graphite base library. Therefore some configuration for the Graphite backend(s) is required as well:

<configSections>
  <section name="graphite" type="Graphite.Configuration.GraphiteConfiguration, Graphite" />
</configSections>
<graphite xmlns="http://github.com/peschuster/Graphite/Configuration">
  <!--<graphite address="127.0.0.1" port="2003" transport="Tcp" />-->
  <statsd address="127.0.0.1" port="8125" prefixKey="test" />
</graphite>

When using the NuGet package Graphite.Elmah all required settings are added to your project automatically during installation:

Install-Package Graphite.Elmah
Posted in .NET, ASP.NET, Monitoring | Tagged , , | Leave a comment

How to Debug OnStart of .NET Windows Services during Development

Have you ever tried to debug a .NET Windows Service during development?

Of course you can attach a debugger to the service process using Debug –> Attach to Process*. But it is practically impossible to debug the OnStart method this way.

One possible solution is to “request” a debugger in your code by using Debugger.Launch(). When you wrap this statement in a conditional precompiler directive you can control when to attach a debugger through your current build configuration:

protected override void OnStart(string[] args)
{
#if DEBUGGER
    Debugger.Launch();
#endif

    // Your code here...
}

To use it, you can create a new build configuration and set this symbol in the build configuration settings of the project:

image

* Note: When the service runs under the SYSTEM user account you need to run Visual Studio “as Administrator” to see the service process in the “Attach to Process” window or attach a debugger instance to it.

Posted in .NET | Tagged , , | Leave a comment

Sending stats to Graphite from within SQL Server

I am playing with Graphite and StatsD with all the different possibilities to record and transmit metrics lately.

My recent addition to the “graphite-client” project is a TSQL CLR procedure for sending stats to Graphite directly from within SQL server: https://github.com/peschuster/graphite-client/tree/master/source/Graphite.TSql.

It is just a simple one-liner in SQL:

exec sp_graphitesend '192.168.0.1', 2003, 'stats.events.myserver.test', 1

Installation of the stored procedure is “described” here: https://github.com/peschuster/graphite-client/blob/master/source/Graphite.TSql/sp_graphitesend.sql

Only restriction is that it requires a “TRUSTWORTHY” database, clr code execution enabled and import of a custom DLL (Graphite.TSql.dll).

A typical scenario for sending stats directly from within SQL Server is e.g. logging of backup or maintenance tasks for being able to put it in correlation with other metrics like cache-hit-ratio or memory usage.

Posted in .NET, Monitoring | Tagged , | Leave a comment

Interop type ‘iTunesAppClass’ cannot be embedded.

iTunes comes with an api you can access from any (.NET) program by adding the COM reference “iTunes 1.xx Type Library” (see iTunes COM for Windows SDK) to your Visual Studio project:

using iTunesLib;
iTunesApp app = new iTunesAppClass();

When trying to instantiate an ‘iTunesAppClass’ object the compiler initially outputs the following error message, although creating an instance of this class is the only way to access iTunes:

“Interop type ‘iTunesLib.iTunesAppClass’ cannot be embedded. Use the applicable interface instead.”

This is due to a setting in the reference properties:

  1. Go to the Solution Explorer.
  2. Right click on References –> iTunesLib and hit Properties.
  3. Set “Embed Interop Types” to False.

image

This solves the described error and you can go on automating iTunes.

Remarks: For German localization settings the error message is “Der Interoptyp “iTunesLib.iTunesAppClass” kann nicht eingebettet werden. Verwenden Sie stattdessen die entsprechende Schnittstelle.”

Posted in .NET | Tagged , , | 1 Comment

PropertyTranslator and Interfaces

I my last post I introduced PropertyTranslator – an easy way to translate computed properties in a LINQ query into their implementation right before execution.

This post covers how PropertyTranslator enables you to use LINQ queries written towards properties of an interface, instead of the implementing class.

The Context

Let’s assume you’ve got an IPerson interface as follows:

public interface IPerson
{
    string DisplayName { get; }
}

Additionally there are the two classes Student and Teacher implementing the IPerson interface.

To keep your code base clean you pay great attention to the DRY principle and want to implement a search algorithm for filtering objects implementing IPerson only once in a single place:

public IEnumerable<T> Search<T>(IEnumerable<T> list, string name) 
    where T : IPerson
{
    return list.Where(p => p.DisplayName.Contains(name));
}

Implementation using PropertyTranslator

Implementing this using PropertyTranslator is straight forward:

public class Student : IPerson
{
    private static readonly CompiledExpressionMap<Student, string> displayNameExpression
        = DefaultTranslationOf<Student>.Property(s => s.DisplayName).Is(s => s.Name + " (" + s.MatrNo + ")");

    public string DisplayName
    {
        get { return displayNameExpression.Evaluate(this); }
    }

    public string Name { get; set; }

    public string MatrNo { get; set; }
}
public class Teacher : IPerson
{
    private static readonly CompiledExpressionMap<Teacher, string> displayNameExpression
        = DefaultTranslationOf<Teacher>.Property(s => s.DisplayName).Is(s => s.Name);

    public string DisplayName
    {
        get { return displayNameExpression.Evaluate(this); }
    }

    public string Name { get; set; }
}

The “magic” happens inside of PropertyTranslator, when the interface type is automatically resolved to the class right before query execution: https://github.com/peschuster/PropertyTranslator/blob/master/src/PropertyTranslator/PropertyVisitor.cs#L57-66

Posted in .NET | Tagged , , | 1 Comment

LINQ: How to dynamically map properties

A few month ago i struggled with calculated properties in Entity Framework model objects.

A property like

public string FullName
{
    get { return this.FirstName + " " + this.LastName; }
}

can’t be used in a LINQ query to the database, because the LINQ provider transforming the expression tree to SQL can’t deal with it. This is kind of obvious, because there is no field named “fullName” or similar in the database, but on the other hand it shouldn’t be to difficult to achieve support for these kind of properties as it is quite simple to translate them into SQL.

The Idea

So I did some research and discovered a blog post by Damien Guard and David Fowler: http://damieng.com/blog/2009/06/24/client-side-properties-and-any-remote-linq-provider. They described exactly what I was trying to do and also provided a ready solution for translating properties in LINQ expressions.

Although their solution is really great, it has some caveats:

  1. You have to include a call to WithTranslations() on every query.
  2. It is not possible to build queries on an common interface for multiple classes (more about this in another blog post).
  3. I wanted to be able to provide different property implementations based on the current thread ui culture (I know, sounds scary…).

So I took a stab at it and tried to add the “missing” functionality. The result is a fork of Microsoft.Linq.Translations named “PropertyTranslator”.

The mayor differences between Microsoft.Linq.Translations and PropertyTranslator are the three points described above. At that time Microsoft.Linq.Translations wasn’t at GitHub, yet. Otherwise I probably would have forked it in the github-sense and tried to contribute back.

PropertyTranslator

So, how does it work? I think this is best described with a few examples:

Basic example

A POCO entity class from EntityFramework.

Although in the database only a FirstName and a LastName field exists, the property Name can be used in queries, because right before execution it is translated to FirstName + ' ' + LastName.

public class Person
{
    private static readonly CompiledExpressionMap<Person, string> fullNameExpression = 
        DefaultTranslationOf<Person>.Property(p => p.FullName).Is(p => p.FirstName + " " + p.LastName);

    public string FullName
    {
        get { return fullNameExpression.Evaluate(this); }
    }

    public string FirstName { get; set; }

    public string LastName { get; set; }        
}

UI culture dependent translations

The context: a database table, mapped with entity framework to POCO entity classes with two fields: EnglishName and GermanName. With the following snippet, you can use the Name property in LINQ queries which resolves to the name (either EnglishName or GermanName) depending on the current ui culture.

public class Country
{
    private static readonly CompiledExpressionMap<Country, string> nameExpression = 
        DefaultTranslationOf<Country>.Property(c => c.Name).Is(c => c.EnglishName);

    static Country()
    {
        DefaultTranslationOf<Country>.Property(c => c.Name).Is(c => c.EnglishName, "en");
        DefaultTranslationOf<Country>.Property(c => c.Name).Is(c => c.GermanName, "de");
    }       

    public string Name
    {
        get { return nameExpression.Evaluate(this); }
    }

    public string EnglishName { get; set; }

    public string GermanName { get; set; }      
}

How to enable PropertyTranslator

PropertyTranslator is on Nuget. So you can just add it to your project using the Package Manager Console.

You can enable PropertyTranslator by adding the PropertyVisitor to your EntityFramework ObjectSets (of course it works not only with EntityFramework but with any LINQ provider).

Best way to do this is by using David Fowler’s QueryInterceptor (also on Nuget):

using QueryInterceptor;
using PropertyTranslator;

public class MyDataContext
{
    ObjectContext context = new MyEfContext();

    public IQueryable<Person> PersonTable
    {
        get
        {
            var objectSet = context.CreateObjectSet<Person>("Persons");

            return objectSet.InterceptWith(new PropertyVisitor());
        }
    }
}

Conclusion

With PropertyTranslator it is really simple to translate calculated properties to their implementation right before execution so that it is possible to use them in LINQ queries with any LINQ provider.

Great thanks to Damien Guard and David Fowler for the general idea and their implementation. I mainly just added an additional layer of abstraction (CompiledExpressionMap) and did some restructuring/fixes to enable a convenient usage with QueryInterceptor and writing queries towards interfaces.

Posted in .NET | Tagged , , , | 1 Comment

How to add an uac shield icon to a MenuItem

Since Windows Vista an application needs administrator privileges to perform some system operations like starting or stopping a Windows service. To gain these privileges you can add an “app.manifest” file to your project in Visual Studio and set the requestedExecutionLevel to requireAdministrator.

In Windows there is always the small shield icon to inform the user that administrator privileges are required for the desired action:

image

To add this icon to your own context menu in a WinForms project the following steps are required:

1. Check that the user currently has no administrator privileges:

public bool HasAdministratorRights
{
    get
    {
        var pricipal = new WindowsPrincipal(WindowsIdentity.GetCurrent());

        return pricipal != null && pricipal.IsInRole(WindowsBuiltInRole.Administrator);
    }
}

2. Use a ContextMenuStrip and ToolStripMenuItems instead of the old ContextMenu and MenuItems.

3. Import the SHGetStockIconInfo method from shell32:

private static class NativeMethods
{
    [DllImport("Shell32.dll", SetLastError = false)]
    public static extern Int32 SHGetStockIconInfo(SHSTOCKICONID siid, SHGSI uFlags, ref SHSTOCKICONINFO psii);

    public enum SHSTOCKICONID : uint
    {
        SIID_SHIELD = 77
    }

    [Flags]
    public enum SHGSI : uint
    {
        SHGSI_ICON = 0x000000100,
        SHGSI_SMALLICON = 0x000000001
    }

    [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct SHSTOCKICONINFO
    {
        public UInt32 cbSize;
        public IntPtr hIcon;
        public Int32 iSysIconIndex;
        public Int32 iIcon;

        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
        public string szPath;
    }
}

4. Fetch the shield icon and create a bitmap out of the HIcon:

private void SetUacShield(ToolStripMenuItem menuItem)
{
    NativeMethods.SHSTOCKICONINFO iconResult = new NativeMethods.SHSTOCKICONINFO();
    iconResult.cbSize = (uint)System.Runtime.InteropServices.Marshal.SizeOf(iconResult);

    NativeMethods.SHGetStockIconInfo(
        NativeMethods.SHSTOCKICONID.SIID_SHIELD, 
        NativeMethods.SHGSI.SHGSI_ICON | NativeMethods.SHGSI.SHGSI_SMALLICON, 
        ref iconResult);

    menuItem.DisplayStyle = ToolStripItemDisplayStyle.ImageAndText;
    menuItem.Image = Bitmap.FromHicon(iconResult.hIcon);
}

That’s all. Now you can restart you application with administrator rights or call another executable with the “runas” verb:

private void RunAsAdmin(string fileName, string args)
{
    var processInfo = new ProcessStartInfo
    {
        Verb = "runas",
        FileName = fileName,
        Arguments = args,
    };

    try
    {
        Process.Start(processInfo);
    }
    catch (Win32Exception)
    {
        // Do nothing...
    }
}
Posted in .NET, UI | Tagged , , , | 2 Comments