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.

QFrame WTC Contest: I won!

A while ago there was a request in the class to persons who want to participate in a .NET contest. Ofcourse Peter and I signed up.

Yesterday was the day of judgment. After waking up at 0500 I drove at 0545 to school, to pick up Peter at about 0620. At 0607 I arrived. Fortunately Peter was also on his way (he told me that he didn’t sleep that good the night before), and off we took, to Kontich, to the office of QFrame.

After driving an hour and 15 minutes we arrived at the building, at about 0730.

10 minutes later our teacher arrived, and the other students. At 0800 we entered the building, drank some coffee, and at 0835 the introduction started. We got the assignment and we started programming.

There was a small lunch at 1200 to 1230. I ate 2 sandwiches and we (Peter and I) were the first to go back for our laptop to continue the task, but we had to wait :P

We programmed our application until 1530, then we got an introduction to Extreme Programming.

At the same time we presented our programs to the jury (1 team at the time).

Finally they told us who the winners where. 3th place for another school. 2nd for the PHL, and 1st for the PHL (Peter and me).

So Peter & I won a BEAUTIFUL laptop, and the year price. But we gave that one to our teacher Mrs. Sporen!

The laptop we won: It’s a Sony VAIO VGN-FW11S:

:D Just great.

After that we went bowling and eating, but that was just cool, but not too interesting to post on my blog ;)

Outlook SendTo Extended: Tooltje voor Outlook

Ik heb de afgelopen 2 dagen aan een klein tooltje gewerkt om wat tekortkomingen van de normale SendTo Email Recipient weg te werken.

De reden dat de titel begint met Outlook is dat het alleen met de volledige Outlook werkt, en dan heb ik het nog niet (NOG NIET! Dat komt nog) met een versie < Office 12 (Office 2007) heb getest.

Als je de installatie uitvoert nestelt het zich in de Send To map (Kopiëren naar in een Nederlandse Windows).

En dan kan je dat gewoon op een map doen, en hij zal alle bestanden in die map kopieren naar een nieuwe mail (recursive, dus gij opent alle onderliggende mappen, en daar in ook weer alle onderliggende mappen…).

Ook maakt hij gewoon een HTML emailtje aan, ipv een stom tekst emailtje.

Ook vraagt hij niet om foto’s te verkleinen, want met het huidig internet is dat echt niet nodig.

Hieronder vind je de code (meer is het niet, buiten wat resources), het project vind je hier (rar), en de gecompileerde installer vind je hier:

using System;
using System.Collections.Generic;
using System.IO;
using Outlook = Microsoft.Office.Interop.Outlook;

namespace OutlookSendToExtended
{
	///

	/// This class creates the mail, adds the files,
	/// and provides a function to display the emailwindow
	///
	/// Main method defined below
	/// 

	class OutlookSendToExtendedMain
	{
		#region Private vars

		///

		/// Holder for the Application entity
		/// 

		private Outlook.Application outlook;

		///

		/// Holder for the mail entity
		/// 

		private Outlook.MailItem mailItem;

		#endregion

		#region Constructor(s)

		///

		/// Constructor
		/// 

		///
array of files/folders
		public OutlookSendToExtendedMain(string[] args)
		{
			//create a new application
			this.outlook = new Outlook.Application();

			//create new emailitem
			this.mailItem = (Outlook.MailItem)outlook.CreateItem(Outlook.OlItemType.olMailItem);

			//loop over the fixed args
			foreach (string fixedArg in this.FixArgs(args))
			{
				//add the attachment
				mailItem.Attachments.Add(fixedArg, Outlook.OlAttachmentType.olOLE, 1, fixedArg);
			}

			//to be implemented
			//mailItem.SendUsingAccount
		}

		#endregion

		#region Methods

		///

		/// Enumerates over the args, expanding the folders in it
		/// 

		///
array of files/folders
		/// array of files
		private string[] FixArgs(string[] args)
		{
			List fixedArgs = new List();

			//loop
			foreach (string arg in args)
			{
				//if it is a directory
				if (Directory.Exists(arg))
				{
					try
					{
						//join the dirs and files
						List listOfAll = new List();

						listOfAll.AddRange(Directory.GetFiles(arg));
						listOfAll.AddRange(Directory.GetDirectories(arg));

						//recursive call
						fixedArgs.AddRange(this.FixArgs(listOfAll.ToArray()));
					}
					catch (Exception)
					{
						//to much exceptions to catch, catch the base.
						//what can we do? maybe talk to user.
						//thinking about this
					}
				}
				else
				{
					//it is a file, add it
					fixedArgs.Add(arg);
				}
			}

			//return the array
			return fixedArgs.ToArray();
		}

		public void DisplayEmail()
		{
			//display the email
			this.mailItem.Display(false);
		}

		#endregion

		#region Static methods

		///

		/// Entrypoint
		/// 

		///
array of files/folders to be attached
		static void Main(string[] args)
		{
			if (args.Length != 0)
				(new OutlookSendToExtendedMain(args)).DisplayEmail();

			return;
		}

		#endregion
	}
}

Even een toelichting bij de Setup: er is een PostBuildEvent gedefinieerd, die wat doet met WiRunSQL.vbs (tooltje om de database van een MSI aan te passen).

Hij voegt DISABLEADVTSHORTCUTS toe met value 1 in de Property tabel.

Waarom? Omdat ik een shortcut maak in de SendTo folder, en aangezien Advertised Shortcuts daar niet werken, moeten we dit afzetten. Dit is de enige manier hiervoor, Visual Studio bied hier geen interface voor aan.

Meer info over Advertised shortcuts vind je hier.

Commentaar? Betere manieren? Laat het me weten bij de comments :)

LINQ to SQL voor SQL Compact Edition

Als je een project maakt, en je wilt een kleinere database hebben in de plaats van een MSSQL database (mdf) kan je altijd overwegen een sdf (Compact edition).

Helaas kan je niet standaard LINQ to SQL klassen gebruiken dan (dbml).

Daarvoor kan je wel dit tooltje gebruiken, en de klassen genereren.
linq to sql

Hier volgt wat je in de verschillende textboxen moet invullen, kan je even gemakkelijk copy/pasten.

Title: Make &Linq classes for Database
Command: %vsspv_windows_sdk_dir%\bin\SqlMetal.exe
Arguments: $(ItemPath) /dbml:DataClasses$(ItemFileName).dbml /pluralize /context:DataContext$(ItemFileName)
InitialDirectory: $(ItemDir)

Dan ga je in je project op een .sdf staan, doe je tools > beneden ‘Make Linq classes for Database’, en dan doe je rechtermuisknop op je project > add extisting item > (alle files laten weergeven) > dubbelklik op de dbml.

That’s it, nu kan je eender waar in je project dit doen:

DataContextFuel dataContextFuel = new DataContextFuel(DataLayer.Properties.Settings.Default.FuelConnectionString);

Natuurlijk wel aanpassen voor jouw context he :)

C#: WPF acceptbutton equivalent Part II

Naar aanleiding van het commentaar van whoami op mijn vorige blogpost ben ik er verder gaan kijken naar het behavior van Button.IsDefault.

Ik heb de volgende testcase gemaakt:


	
		
			
			
		
		
		
	

En de volgende code backend:

using System.Windows;

namespace TestCase
{
	///

	/// Interaction logic for Test.xaml
	/// 

	public partial class Test : Window
	{
		public Test()
		{
			InitializeComponent();
		}

		private void button_Click(object sender, RoutedEventArgs e)
		{
			MessageBox.Show(sender.ToString());
		}
	}
}

Als je dit start zal je zien dat beide knoppen zijn gefocust.

Duw je dan op enter wordt de eerste knop gefocust (er wordt geen knop getriggert), en als je daarna nogmaals op enter duwt wordt er op de eerste knop getriggerd.

Gek behavior dus.

C#: WPF acceptbutton equivalent.

Vroeger kon je in een Windows.Form het volgende doen:

Form form = new Form();
//voeg wat dingen toe aan form
Button enterButton = new Button("Klik hier");
form.AcceptButton = enterKnop();

Resultaat: het form klikt ‘zelf’ op de enterKnop als je op enter duwt.

In WPF is het heel anders, vanuit een ander oogpunt bekeken, namelijk niet het Form (Window) zelf, maar de knop.

Button enterKnop = new Button();
enterKnop.Content = "Klik hier";
enterKnop.IsDefault = true;

Button.IsDefault dus :)

C#: System.Windows.Forms.Combobox issues

Ik ben al enige tijd bezig met een chatApp, zoals jullie weten. Voor de logfunctie wou ik iets moois, dus ik besloot een combobox te maken, waarbij steeds de nieuwe logmessage aan wordt geappended & dan die wordt geselecteerd, waardoor ge mooi de laatste logmessage in beeld krijgt.

Zo dus:

Combobox Readonly

Maar hoe lukt dat?

Na lang zoeken, en zelfs het proberen van het extenden van de combobox, en daarbij capturen van allerhande events (wat allemaal niet 100% werkt) is de oplossing SUPERSIMPEL:

this.comboBoxLog.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;

Meer is er echt niets aan.

M’n programmatje vlot ook heel mooi. Als sneak preview deze screenshot:

ChatHere screenshot

C# 3.0, .NET 3.5: Automatic properties

Properties, sommigen gebruiken het, sommigen niet. Zelf heb ik leren programmeren met getters & setters (vanuit Java). Sinds korte tijd gebruik ik toch properties in C#, omdat het eenvoudiger is, en overzichtelijker.

Voorbeeldje:

class TestProps
{
	private String nick;

	public TestProps(String nick)
	{
		this.nick = nick;
	}

	//de C# manier:
	public String Nick
	{
		get
		{
			return this.nick;
		}
		set
		{
			this.nick = value;
		}
	}

	//de Java manier (zelfde syntax in C#)
	public String getNick()
	{
		return this.nick;
	}

	public void setNick(String nick)
	{
		this.nick = nick;
	}
}

Dus ofwel gebruikt ge de C# manier, ofwel de Java manier, whatever you wish, beiden hebben hetzelfde eindresultaat.

Maar nu zit deze nieuweigheid in C#:

class TestProps2
{
	public TestProps2(String nick)
	{
		this.Nick = nick;
	}

	public String Nick { get; set; }
}

That’s it! Geen interne private variable meer, dat wordt automatisch door de compiler gedaan. Veel korter dus, en ge kunt er op dezelfde manier aan als de properties op de C# manier :)