Click here to Skip to main content

Alex Perepletov - Professional Profile

2,824
Author
179
Authority
12
Debator
24
Editor
6
Organiser
127
Participant
0
Enquirer
No Biography provided
Member since Friday, January 31, 2003 (9 years, 3 months)

For more information on Reputation please see the FAQ.
 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
  Refresh
RantControl.GetStyle() should be public. Pin
Sunday, March 15, 2009 7:52 PM
I have a recursive function on my form that sets backgrounds of all Controls on it to Color.Transparent. It was a happy function until the moment I put a DataGridView on the form. DataGridView doesn't support transparent color, and the function blew up in an exception.
 
I could put an empty try catch around the color assignment line, but that is just way too ugly of a "solution".
 
The only way to determine whether a Control supports transparent background is to call the GetStyle() function. Too bad it's protected. Is there any good reason for this function being protected and not public? No way someone is going to inherit from every control just to get to those flags.
 
As usual, Reflection saves the day. Write an extension method that gets the flag in question. Well, it would probably make sense to write an extension that exposes the GetStyle(), but I wanted more readability in my code.
 
Anyway, this is the extension method:
public static bool SupportsTransparentBackColor(this Control control)
{
	// Protected function GetStyle(ControlStyles flag) determines whether
	// a control supports transparent background color.
	Type t = control.GetType();
	MethodInfo miGetStyle = t.GetMethod(
		"GetStyle",
		BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.FlattenHierarchy,
		null,
		new Type[] { typeof(ControlStyles) },
		null);
	// Let's see what that method returns.
	return (bool)miGetStyle.Invoke(control, new object[] {
		ControlStyles.SupportsTransparentBackColor
	});			
}
 
And that is how it's used (I wish there were extension Properties too)
if (ctl.SupportsTransparentBackColor())
{
	ctl.BackColor = Color.Transparent;
}

 
GeneralRetrieve PropertyInfo of current property. Pin
Sunday, December 28, 2008 5:35 AM
Many properties of my project perform input validation. Exceptions are thrown when input is invalid. I decided to automate generation of the error message that gets displayed in case of these exceptions. The very least that I need to know to display this message is the name of the property that threw an exception.
 
At first, I changed set accessors of some properties to throw property name as the Exception message. Like so:
 
public int MyIntProperty
{
	get { return _myInt; }
	set
	{
		if (value == 10)
			throw new Exception("MyIntProperty");
		_myInt = value;
	}
}
 
This has a drawback of manually updating the string that gets thrown. One can forget to do so when changing property name, or make a typo. Can’t we make computer do this for us? How can we find information on property from inside that property?
 
Information on currently executing method is found using static method MethodBase.GetCurrentMethod(). Too bad there is no PropertyInfo.GetCurrentProperty() method. That is basically what we want.
 
MethodBase.GetCurrentMethod() still comes to the rescue. Compiler transforms get accessors into get_PropertyName methods, while set accessors are transformed into set_PropertyName methods. Calling MethodBase.GetCurrentMethod() from the set accessor of the MyIntProperty above returns a setAccessor = {Void set_MyIntProperty(Int32)}
 
So, we have the set accessor method. Now all we need to do is to loop through Properties of our object’s Type, and find the Property that has set_MyIntProperty set accessor. PropertyInfo.GetSetMethod() looks up the Property set accessor function. The following function finds the PropertyInfo for a specific set accessor:
 
private PropertyInfo FindMyProperty(object obj, MethodBase setAccessor)
{
	Type type = obj.GetType();
	foreach (PropertyInfo pi in type.GetProperties())
	{
		MethodInfo mi = pi.GetSetMethod();
		if (MethodInfo.Equals(mi, setAccessor))
		{
			return pi;
		}
	}
	return null;
}
 
Here’s an example of a modified MyIntProperty that uses the new function to find its own PropertyInfo:
 
using System;
using System.Reflection;
 
namespace CurrentProperty
{
	class Program
	{
		private float _myFloat = 0f;
		private int _myInt = 0;
 
		static void Main(string[] args)
		{
			Program p = new Program();
 
			p.MyFloatProperty = 10f;
			p.MyIntProperty = 10;
		}
 
		public float MyFloatProperty
		{
			get { return _myFloat; }
			set
			{
				if (value == 10f)
					throw new Exception(FindMyProperty(this, MethodBase.GetCurrentMethod()).Name);
 
				_myFloat = value;
			}
		}
 
		public int MyIntProperty
		{
			get { return _myInt; }
			set
			{
				if (value == 10)
					throw new Exception(FindMyProperty(this, MethodBase.GetCurrentMethod()).Name);
 
				_myInt = value;
			}
		}
 
		private PropertyInfo FindMyProperty(object obj, MethodBase setAccessor)
		{
			Type type = obj.GetType();
			foreach (PropertyInfo pi in type.GetProperties())
			{
				MethodInfo mi = pi.GetSetMethod();
				if (MethodInfo.Equals(mi, setAccessor))
				{
					return pi;
				}
			}
			return null;
		}
	}
}

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   


Advertise | Privacy | Mobile
Web04 | 2.5.120528.1 | Last Updated 28 May 2012
Copyright © CodeProject, 1999-2012
All Rights Reserved. Terms of Use
Layout: fixed | fluid