August 5, 2009

Extensions Methods with .NET 2.0

I've often wished I could have my extension methods on .NET 2.0 since that's what I build with most of the time. Now with some help from Nate Kohari and Scott Hanselman I can. Just add the following to your .NET 2.0 project.
namespace System.Runtime.CompilerServices
{
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false,
Inherited = false)]
public class ExtensionAttribute : Attribute
{
}
}
Since the project is still compiled with the 3.x or 4.x compiler the extensions are properly added.

July 29, 2009

How to Get a Parent Form from a Component

I found much of this at Code Project, but I think my implementation is cleaner.

Since a component doesn’t have a Parent property like a control does it is often difficult to Invoke in a component which is a pity since a component is more likely to need it. This solution creates an abstract class that adds the Parent property to the component class. If you merely derive your class from the AdvancedComponent class instead of from the Component class you will get the Parent property as well as the FindForm() method.

using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
using System.Windows.Forms;
using System.ComponentModel.Design;
namespace MyComponents
{
public class AdvancedComponent : Component
{
private Form m_parent_form;
public AdvancedComponent()
: base() { }
/// <summary>
/// Overrides the ISite property
/// so that it is set when the
/// component is placed on a form.
/// </summary>
public override ISite Site
{
get
{
return base.Site;
}
set
{
base.Site = value;
GetFormInstance();
}
}
private void GetFormInstance()
{
IDesignerHost host = null;
if (base.Site != null)
{
host = base.Site.GetService(typeof(IDesignerHost)) as IDesignerHost;
if (host != null)
{
m_parent_form = host.RootComponent as Form;
}
}
}
/// <summary>
/// Creates a Parent property
/// that can be used to find the
/// parent form.
/// </summary>
public Form Parent
{
get { return m_parent_form; }
set
{
m_parent_form = value;
}
}
/// <summary>
/// Implements a FindForm method
/// similar to Control.FindForm
/// </summary>
/// <returns>The contents of the Parent property</returns>
public Form FindForm()
{
return Parent;
}
}
}

July 28, 2009

Overriding the Text Property of a WinForms UserControl

From Rockford Lhotka:

“Every time I go to override the Text property in a Windows Forms UserControl I have to go find this one little attribute that I can never remember...

It is easy enough to remember to make the property Browsable(true), but it is that other attribute that's hard to remember: DesignerSerializationVisibility(DesignerSerializationVisibility.Visible).

This web page not only answers the question, but includes a nice summary of all the System.ComponentModel attributes.

At least next time I know I can search my own blog to find the answer :)”

July 19, 2009

Camping

This week was spent camping with my older boy's boy scout troop at Many Point Scout Camp. I learned a few things:


  1. I can throw a tomahawk better than most, but still only hit one out of five.
  2. I'm not too bad with a .22 rifle, but there are ten year-old boys that can put me to shame.
  3. My cot was designed with young children in mind, I can get either my head or my feet on but not both and my arms do not fit on at the same time as my body.
  4. Never, ever, go camping with Rich. He's a nice guy but he brings in the bad weather.

I put photos up on Flickr, but since they show other people's children most photos are private. When the rain cleared up a bit on our last evening there I got some beautiful photos of the sunset over the lake.


The camp had some sessions for the adult leaders, one was about Ethics In Action which is also known as D.E.L.T.A. This program helps leaders use group games as a starting point of discussion to teach the troop communication and teamwork as well as other values. The next day we actually got to see one of the counselors work with the troop to go through some of the exercises and the discussion time afterward. It was interesting that although the troop failed miserably at completing a given task they were able to get some good lessons from the exercise.

July 11, 2009

.NET Extension Methods and Enumerations

Much of my code play recently has been with .NET/Mono in C#. One of the cooler aspects of 3.x has been extension methods by which I can add methods to established types. For instance if I'm doing a bunch of range checking on integers the traditional way would be:

if ((3 <= i) && (i <= 9))
{
...
}

With extension methods I can create an extension that allows me to do:

if (i.Within(3,9))
{
...
}


I do this by creating a static class like below:

static class MyExtensionMethods
{
public static bool Within(this int me, int a, int b)
{
// this is faster if we require a to be the
// lower bound and b to be
// the upper bound, but to be complete...
return (Math.Min(a,b) <= me) &&
(me <= Math.Max(a,b));
}
}


The tricky part is applying this to certain types such as enumerations. One thing I do a lot with enums is testing if an or'd set contains one given enum value. For instance to determine if the left mouse button is pressed I would use:

if ((Control.MouseButtons & MouseButtons.Left) == 
MouseButtons.Left)
{
// Handle the left button down
}


So I can create an extension method for MouseButtons enum:

public static bool Contains(this MouseButtons me, 
MouseButtons other)
{
return (me & other) == other;
}


That's handy but I don't want to create this for every enum I touch. So now I want to create an extension method that extends any enum. The first try is:

public static bool Contains(this Enum me, Enum other)
{
return (me & other) == other;
}

This works but I can do Control.MouseButtons.Contains(MenuMerge.Add) which might work but isn't really valid. So let's try to change it:

public static bool Contains(this T me, T other)
where T : enum
{
return (me & other) == other;
}

This is how it should work, however MS in all their wisdom has decided enums cannot be set as a where statement on methods or classes. So we have to cheat and introduce some possible problems that wouldn't show up until run time. We can use a struct as a where clause and enums are structs, but then we have to test that the type T is actually an enum. This leads to the final form:

public static bool Contains(this T me, T other)
where T : struct
{
if (!typeof(Enum).IsAssignableFrom(typeof(T)))
thrown new InvalidCastException();

return (me & other) == other;
}

This works, but the compiler won't throw an exception on using the Contains method on regular structs. You will get a run time exception but that can be messy so use at your own discretion.

Welcome

I guess it's customary to write a welcome post first, so here I go. This blog is more of an online note repository for me than a place for people to follow my ideas. If you find anything useful here it's probably by accident.


Who am I? Well that's something I hope to explore on here, but simply I'm a Christian with an inquisitive technological bent. I would call myself a fundamentalist because I believe the fundamentals of the Christian faith, but I am not what most people call a fundamentalist instead I'm somewhat liberal in my thinking.


Most of my technology discussions will have to be about code since I am bound by my employer regarding my hardware design.