Jun 25, 2009

Lambda Example 1


public class TestLambda
{
delegate int AddOneDgt(int x);

/// <summary>
/// Details at: http://blogs.msdn.com/ericwhite/pages/Lambda-Expressions.aspx
/// </summary>
public static void DoWork()
{
int a = 3;
// Pointer to a static function
AddOneDgt addOneFctPtr = new AddOneDgt(A.AddOne);
// Pointer to an instance function
AddOneDgt addOneFctPtr1 = new AddOneDgt(new A().AddOneInst);
// C# 2.0 - Anonymous functions
AddOneDgt addOneInlinePtr = new AddOneDgt(delegate(int x) { return x + 1; });
// C# 3.0 - Lambda
AddOneDgt addOneLambdaPtr = x => x + 1;

Console.WriteLine(string.Format("A. {0} + 1 = {1}", a, addOneFctPtr(a)));
Console.WriteLine(string.Format("B. {0} + 1 = {1}", a, addOneFctPtr1(a)));
Console.WriteLine(string.Format("C. {0} + 1 = {1}", a, addOneInlinePtr(a)));
Console.WriteLine(string.Format("D. {0} + 1 = {1}", a, addOneLambdaPtr(a)));
}

public class A
{
public static int AddOne(int x)
{
return x + 1;
}

public int AddOneInst(int x)
{
return x + 1;
}
}
}


Output:
A. 3 + 1 = 4
B. 3 + 1 = 4
C. 3 + 1 = 4
D. 3 + 1 = 4

Jun 19, 2009

How to avoid multiple instances of your .Net application

A very good method is using a mutex:

Global mutex

Auto-implemented properties in C# 3.0

They are NOT the equivalent of a public field. (WHY?)

private string Name { get; set }

You can have a private setter so the prop becomes immutable (ie unchangable after the object is instantiated)

private string Name { get; private set; }

Jun 13, 2009

C# yield example


private void Form1_Load(object sender, EventArgs e)
{
int i = 0;
string[] arr = new string[] { "bob1", "can", "bob2", "boB3", "everyday", "Bob4" };

foreach (string str in FindBobs(arr))
{
Console.WriteLine(++i + ". " + str);
}
}
static IEnumerable<string> FindBobs(string[] arr)
{
foreach (string str in arr)
{
if (str.Equals("bob3", StringComparison.OrdinalIgnoreCase))
yield break;
if (str.StartsWith("bob", StringComparison.OrdinalIgnoreCase))
yield return str;
}
}

Output:
1. bob1
2. bob2

If the "yeild break" statement is commented the output is:
1. bob1
2. bob2
3. boB3
4. Bob4

C# short-circuit logical operators

"&&" and "||" operators use short-circuit. Thus,

if (false && expr1)
{
// Won't evaluate expr1
}

Or

if (true || expr2)
{
// Won't evaluate expr2
}

If you want both sides to be evaluated use the "&" and "|" operators

Jun 12, 2009

Links

Hidden Features of C#

Yield Explained

Howto avoid having to use ToUpper() in string comparisons

Instead of using:

if (myString.ToUpper() == theirString.ToUpper) { ... }

Use this:

if( myString.Equals( theirString, StringComparison.OrdinalIgnoreCase ) { ... }


Thanks to: Ralph

Jun 11, 2009

Howto get the TopMost Form in a WinForm App using Win32 API


public class Win32
{
public const int GW_HWNDNEXT = 2; // The next window is below the specified window
public const int GW_HWNDPREV = 3; // The previous window is above
public const int GW_HWNDFIRST = 0; // TopMost Windows
private const int SW_HIDE = 0;

[DllImport("user32", CharSet = CharSet.Auto, SetLastError = true, ExactSpelling = true)]
public static extern IntPtr GetWindow(IntPtr hwnd, int wFlag);

[DllImport("user32.dll")]
static extern IntPtr GetTopWindow(IntPtr hWnd);

[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool IsWindowVisible(IntPtr hWnd);

[DllImport("user32.dll", CharSet = CharSet.Auto, EntryPoint = "GetWindow",SetLastError = true)]
public static extern IntPtr GetNextWindow(IntPtr hwnd, [MarshalAs(UnmanagedType.U4)] int wFlag);

[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);

[DllImport("user32.dll")]
private static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);


/// <summary>
/// Cautam Forma care este TopMost si o returnam.
/// Iteram doar prin ferestrele care sunt vizibile, incepand cu cel mai mare Z-order si continuand
/// cu cele care se ascund in spatele ei.
/// </summary>
/// <returns>Forma care este topmost in momentul apelarii functiei</returns>
public static Form GetTopMostWindow(IntPtr hWnd_mainFrm)
{
Form frm = null;

IntPtr hwnd = GetTopWindow((IntPtr)null);

//StringBuilder sb = new StringBuilder(256);
//GetWindowText(hwnd, sb, 256);
//Console.WriteLine("TOP WINDOW: " + sb.ToString());

if (hwnd != IntPtr.Zero)
{
while ((!IsWindowVisible(hwnd) || frm == null) && hwnd != hWnd_mainFrm)
{
// Get next above window if not visible
hwnd = GetNextWindow(hwnd, GW_HWNDNEXT);

//GetWindowText(hwnd, sb, 256);
//Console.WriteLine(sb.ToString().Length == 0 ? "Fereastra fara nume" : sb.ToString());

try
{
frm = (Form)Form.FromHandle(hwnd);
}
catch
{
// Crapa daca incercam sa facem cast la un handle care nu e de tip Form
// In mod normal daca nu poate face cast returneaza null.
// Da la unele cast-uri crapa... pana mea!
}
}
}

return frm;
}
}

Jun 10, 2009

How to avoid situations where Visual Studio Designer crashes because of code running in Design Mode

The VS Designer will try to create your UI and will call the control constructor. If you have code that connects to a DB for instance in the constructor, the Designer will crash. To avoid that, a simple check [ if (!DesignMode) { ...get DB connection...} ] using the following property will do the trick:


/// <summary>
/// Verificam daca procesul care ruleaza codul este VisualStudio si ignoram ca sa nu ne crape in Designerul VS.
/// </summary>
public static bool DesignMode
{
get { return (System.Diagnostics.Process.GetCurrentProcess().ProcessName == "devenv"); }
}


Method Nr. 2:

using System.ComponentModel;

public static bool DesignModeLicUsage
{
get
{
return (LicenseUsageMode.Designtime == LicenseUsageMode.Designtime);
}
}

Jun 6, 2009

C# Events Tutorial

In the class that throws the events:

First declare a delegate:

private delegate void AudioIsPlayingHandler(MediaElement elem);


Then declare an event:

private event AudioIsPlaingHandler OnAudioIsPlaying;


Somewhere, the class throws the event:

if (OnAudioIsPlaying != null)
OnAudioIsPlaying(elem); // Raise the event and pass some data


Now, in a class that has an instance of the previous class:

First, attach to the event in obj A, an instance of the previous class:

A.OnAudioIsPlaying += new System.EventHandler(A_OnAudioIsPlaying);


Then, in the handler function:

private void A_OnAudioIsPlaying(MediaElement elem)
{
// Do something with the data received
}

Finally, check this out for a lot more details:
Visual Studio Developer Center - Events Tutorial

Jun 5, 2009

Draw Rectangle Over UltraGrid

This is some basic stuff about how to draw lines in C#:
Drawing lines in C#

This tries to help with the flickering problem. Didn't get it to work over an UltraGrid:
Don't Flicker! Double Buffer!

This works on a Windows Form but couldn't get it to work over a control containing an UltraGrid, and it uses Win32 API to draw:
C# Rubber Rectangle

This works fine in a Windows Form but gives artifacts over the UltraGrid:
How to draw a rubber band rectangle or a focus rectangle in Visual C#


I also had my own implementation which flickered:



private Point _mouseStart, _mouseCurrent;
private bool _bPaintSelectionRect = false;

private void uGrid_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
_mouseStart = e.Location;
...
}
}

private void uGrid_MouseUp(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
// TODO: Select cells in the rectangle
_bPaintSelectionRect = false;
}
}

private void uGrid_MouseMove(object sender, MouseEventArgs e)
{
// If user is holding the left button and dragging, draw a rectangle
if (e.Button == MouseButtons.Left && _mouseStart != null)
{
// Save current mouse position as it moves
_mouseCurrent = e.Location;
// Allow the paint event to draw the rectangle
_bPaintSelectionRect = true;
}

}

private void uGrid_Paint(object sender, PaintEventArgs e)
{
if (_bPaintSelectionRect)
{
Graphics g = e.Graphics;
Pen solidPen = new Pen(new SolidBrush(Color.Gray));
//solidPen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash;
solidPen.DashPattern = new float[] { 1, 1 };

// Normalize the rectangle
int x = _mouseCurrent.X > _mouseStart.X ? _mouseStart.X : _mouseCurrent.X;
int y = _mouseCurrent.Y > _mouseStart.Y ? _mouseStart.Y : _mouseCurrent.Y;
int width = Math.Abs(_mouseCurrent.X - _mouseStart.X);
int height = Math.Abs(_mouseCurrent.Y - _mouseStart.Y);

g.DrawRectangle(solidPen, x, y, width, height);

// Force the redraw (causes flicker) - don't call Invalidate()
// and you won't see the rectangle
uGrid.Invalidate();
}
}