WinForms: Labels and ampersands

Today I bumped into this problem at work. I had a label on a form and I had to display an employee’s department.

Quite easy, but the department sometimes contains an ampersand. And that ampersand was not displayed. I went looking for this problem and I bumped into this property (in System.Windows.Forms.Label): Label.UseMnemonic Property

Setting this property true means: an ampersand that precedents a character underlines that character, so that it can be used in conjunction with the alt key.

The problem arises when you for example pull a department from the database with an ampersand (for example: shipping & hauling). Putting this into the label causes the & not to be displayed since the label assumes that the ampersand means ‘underline the character after the ampersand’.

To display the ampersand you’ve got two choices:

  1. set UseMnemonic to false so that it doesn’t parse the ampersand.
  2. if you need the mnemonic: replace the & with &&, that displays 1 ampersand in the label.

LINQ to Entities: EntityReference

When creating one to many relationships one might bump into the following problem:

Consider the following database design:

Tables:

Customers
-Id
-FirstName
-LastName
-…snip…
-City

Cities
-Id
-Name
-Zip

With a many to one relation from Customers.City to Cities.Id

While this is easy to do in SQL, the LINQ to Entities syntax might seem a bit different.

Consider the following piece of code:

City c = (from city in ctx.CitySet
where city.Name == cityName && city.Zip == cityZip
select city).FirstOrDefault();

This selects the city (if it exists) or null.

Now the problem is: IF the city exists, how do I point the current customer’s city to that particular city.

I tried this:

//customer is a customer object
customer.City = c;

But that resulted in duplicate cities in the database.

The solution was actually quite easy, I browsed through all the properties (Intellisense!) and found this:

customer.CityReference.EntityKey = c.EntityKey;

This resulted in the one to many relationship I had in mind. No duplicate cities in my database.

I love database normalization!

WPF: FileDialogs on Vista 64-bit, use the Manifest!

Rick Brewster made this comment on my previous post about the Inconsistent FileDialogs.

So I decided to fire up his solution:

I’ve created an empty WPF project, with a Window called ‘Main’ with the following code:

using System.Windows;
using Microsoft.Win32;

namespace OpenFileDialogNewStyle
{
	///

	/// Interaction logic for Main.xaml
	/// 

	public partial class Main : Window
	{
		///

		/// Constructor
		/// 

		public Main()
		{
			this.InitializeComponent();

			OpenFileDialog myOpenFileDialog = new OpenFileDialog();

			myOpenFileDialog.ShowDialog();
		}
	}
}

This opens the ‘old’ style FileDialog, with the outdated icons.

old-filedialog

To resolve this you can add a manifest in your project:

add-manifest

The manifest should be named NameOfYourStartUpProject.exe.manifest (as pointed out above), it should be a text file containing the following code:



	
	Description
	
		
			
		
	

Change the name on the 5th line to the name of your project!

Now go to properties and point to the manifest.

select-manifest

Now compile, and test if you see the new type icons :)

new-filedialog

Entity Framework: SDF: Server-generated keys and server-generated values are not supported by SQL Server Compact.

(My friend Peter pointed me to this so I am writing this on his behalf)

Basic setup:

A simple application, an SDF (Microsoft SQL Server Compact file) and the Entity Framework.

So I created the project, added the files, created the tables, made a model, and wrote this class:

namespace LinqToEntities
{
	class Program
	{
		static void Main(string[] args)
		{
			using (Database1Entities ctx = new Database1Entities())
			{
				Test myTest = new Test() { Value1 = "Blah", Value2 = "Blah2" };

				ctx.AddToTestSet(myTest);

				ctx.SaveChanges();
			}
		}
	}
}

And this gives me a nice error on ctx.SaveChanges();sqlserver-ce

(Big image!!!)

The problem is not the database, like the error says. But the problem is that the EF just doesn’t understand it.

Here are some ‘workaround’, I quote it because I don’t really consider them a workaround.:

  • Disable autoincrement, and manually fetch the highest id, and then insert. This could lead to corruption if you are in a multi threaded  environment.
  • Use a SqlCeCommand

But it’s a breaking issue I think, and I hope they fix it in the next version.

WPF: Inconsistent FileDialogs on Vista 64-bit.

You might run into this problem:

When you try to make an Open/SaveFileDialog on in a WPF program, you might see that the dialog is displayed with the old graphics:

savefiledialog

*yuk*

This seems to be caused by a detection inconsistency somewhere inside the Microsoft.Win32.

To solve the problem you could manually add a Reference to System.Windows.Forms, and use the System.Windows.Forms.OpenFileDialog or the System.Windows.Forms.SaveFileDialog.

This will display the beautiful Open/SaveFileDialog on Vista 64-bit.

Good luck :)

C#: Structs and parameters

struct MyStruct
{
	public int X { get; set; }
	public int Y { get; set; }

	public MyStruct(int x, int y)
	{
		this.X = x;
		this.Y = y;
	}
}

Will trigger an error on line 8:

The ‘this’ object cannot be used before all of its fields are assigned to

So I thought I might fix it by assigning a value to the fields. Since we have automatic properties, let’s convert them to normal properties:

struct MyStruct
{
	private int _x = 0;
	public int X
	{
		get
		{
			return _x;
		}
		set
		{
			_x = value;
		}
	}
	private int _y = 0;
	public int Y
	{
		get
		{
			return _y;
		}
		set
		{
			_y = value;
		}
	}

	public MyStruct(int x, int y)
	{
		this.X = x;
		this.Y = y;
	}
}

Let’s press F5. Oeh noes, another error:

‘MyStruct._x’ cannot have its instance field initializers in structs

So you can’t do field initialization in a struct (apart from in a function / constructor / getter / setter).

Let’s go back to the first piece of code and make it work by adding 7 characters:

struct MyStruct
{
	public int X { get; set; }
	public int Y { get; set; }

	public MyStruct(int x, int y) : this()
	{
		this.X = x;
		this.Y = y;
	}
}

The this() initializes the struct, and in the constructor itself the struct’s vars & properties are set to their default values. It’s weird though that an int needs initialization…

C#: Extending Outlook.(_)Application.

Does not work.

Outlook.Application and Outlook._Application are both interfaces. And I want to use them as a class in my program (I don’t know how they made that work).

I wanted to extend Outlook.Application and add a simple method to create a new email. But that does not work since you have to implement a bunch of methods which I hardly understand.

Thank Microsoft for creating extension methods, so here is my solution:

using System;
using Outlook = Microsoft.Office.Interop.Outlook;

namespace SendToExtended
{
	static class OutlookExtensions
	{
		///

		/// Creates and returns an Microsoft Outlook MailItem
		/// 

		///
an instantiated Outlook application
		/// A new MailItem object
		public static Outlook.MailItem CreateMailItem(this Outlook.Application outlook)
		{
			if (outlook == null)
				throw new ArgumentException("outlook parameter cannot be null");

			return (Outlook.MailItem)outlook.CreateItem(Outlook.OlItemType.olMailItem);
		}
	}
}

A fluent approach to C# parameter validation

Normally I don’t do this, but since this is such a great article:

http://blog.getpaint.net/2008/12/06/a-fluent-approach-to-c-parameter-validation/

From the creator of Paint.NET.

It’s really worth reading, if you do a lot of parameter validation. It might come in handy for your forms, or maybe even for a website.

I think I’ll write something based on that really soon :)

C#: Smaller syntax for event handlers.

Using lambda functions you can shorten your event handlers.

E.g.:

With a normal event hander:

class Test
{
	private Timer timer;

	private void Timer_Elapsed(object sender, ElapsedEventArgs e)
	{
		Console.WriteLine(string.Format("Object: {0} sends: {1}", sender, e));
	}

       public Test()
	{
		this.timer = new Timer();

		this.timer.Elapsed += new ElapsedEventHandler(this.Timer_Elapsed);

		this.timer.Interval = 100;
		this.timer.Start();
	}
}

With an anonymous function:

class Test
{
	private Timer timer;

        public Test()
	{
		this.timer = new Timer();

		this.timer.Elapsed += delegate(object sender, ElapsedEventArgs e)
					 {
						 Console.WriteLine(string.Format("Object: {0} sends: {1}", sender, e));
					 };

		this.timer.Interval = 100;
		this.timer.Start();
	}
}

And with an anonymous lamba:

class Test
{
	private Timer timer;

        public Test()
	{
		this.timer = new Timer();

		this.timer.Elapsed += (sender, e) => Console.WriteLine(string.Format("Object: {0} sends: {1}", sender, e));
		//or you can explicitly type your parameters:
		this.timer.Elapsed += (object sender, ElapsedEventArgs e) => Console.WriteLine(string.Format("Object: {0} sends: {1}", sender, e));

		this.timer.Interval = 100;
		this.timer.Start();
	}
}

And with a named lamda:

class Test
{
	private ElapsedEventHandler elapsedEventHander;
        private Timer timer;

        public Test()
	{
		this.timer = new Timer();

		this.elapsedEventHander = (sender, e) => Console.WriteLine(string.Format("Object: {0} sends: {1}", sender, e));

		this.timer.Elapsed += this.elapsedEventHander;

		this.timer.Interval = 100;
		this.timer.Start();
	}
}

Which one to take? The one that suits you and your current application / case!

Sidenote: sorry for the layout, I will fix it ASAP. Fixed :)

QFrame WTC Contest: The code

As promised: The code Peter and I wrote last Thursday.

Please keep the following guidelines in mind:

  1. Attach the database to a SQL 2008 database (no 2005 does not works. If you really want it I can convert it for you).
  2. Change the connection string (changing ‘LAPTOP-SNAKE\SQLEXPRESS’) to your database provider
  3. Run it :)

Good luck, should you have any questions, please post ‘m down here.