Click here to Skip to main content
15,893,622 members
Articles / Web Development / ASP.NET

Creating a custom DataSourceControl with full design time support

Rate me:
Please Sign up or sign in to vote.
4.50/5 (11 votes)
19 Jun 20078 min read 64.7K   984   68  
An article on creating a DataSourceControl with full design time support
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Data;
using System.Drawing;
using System.Reflection;
using System.Text;
using System.Windows.Forms;

namespace Manu.Web.UI.WebControls
{
	public partial class ConfigureDataSource : Form
	{
		#region Fields

		private IServiceProvider _serviceProvider;
		private CustomDataSource _component;
		private CustomDataSourceDesigner _designer;

		#endregion

		#region Properties

		internal string TypeName
		{
			get {
				// gets the selected type
				TypeItem selectedType = ddlTypes.SelectedItem as TypeItem;

				// return the selected type
				if (selectedType != null){
					return selectedType.Name;
				} else {
					return String.Empty;
				}
			}
			set {
				// iterate through all the types searching for the requested type
				foreach (TypeItem item in ddlTypes.Items){
					// if we have found it, select it
					if (String.Compare(item.Name, value, true) == 0) {
						ddlTypes.SelectedItem = item;
						break;
					}
				}
			}
		}

		internal string SelectMethod
		{
			get {
				// gets the select method
				string methodName = String.Empty;

				if (MethodInfo != null) {
					methodName = MethodInfo.Name;
				}

				return methodName;
			}
			set	{
				// iterate through all the types searching for the requested type
				foreach (MethodItem item in ddlMethods.Items) {
					// if we have found it, select it
					if (String.Compare(item.MethodInfo.Name, value, true) == 0) {
						ddlMethods.SelectedItem = item;
						break;
					}
				}
			}
		}

		internal MethodInfo MethodInfo
		{
			get {
				MethodItem item = ddlMethods.SelectedItem as MethodItem;

				if (item == null) {
					return null;
				}

				return item.MethodInfo;
			}
		}

		#endregion

		#region Methods

		public ConfigureDataSource()
		{
			InitializeComponent();
		}

		public ConfigureDataSource(IServiceProvider provider, CustomDataSourceDesigner designer)
		{
			InitializeComponent();

			_serviceProvider = provider;
			_component = designer.Component as CustomDataSource;
			_designer = designer;

			// fills the dropdownlist with the available types
			DiscoverTypes();

			// configure the form with the properties of the component
			TypeName = _component.TypeName;
			SelectMethod = _component.SelectMethod;
		}

		private void DiscoverTypes()
		{
			// try to get a reference to the type discovery service
			ITypeDiscoveryService discovery = null;
			if (_component.Site != null) {
				discovery = (ITypeDiscoveryService)_component.Site.GetService(typeof(ITypeDiscoveryService));
			}

			// if the type discovery service is available
			if (discovery != null) {
				// saves the cursor and sets the wait cursor
				Cursor previousCursor = Cursor.Current;
				Cursor.Current = Cursors.WaitCursor;

				try {
					// gets all types using the type discovery service
					ICollection types = discovery.GetTypes(typeof(object), true);
					ddlTypes.BeginUpdate();

					ddlTypes.Items.Clear();

					// adds the types to the list
					foreach (Type type in types) {
						TypeItem typeItem = new TypeItem(type);
						ddlTypes.Items.Add(typeItem);
					}
				} finally {
					Cursor.Current = previousCursor;
					ddlTypes.EndUpdate();
				}
			}
		}

		private void ddlTypes_SelectedIndexChanged(object sender, EventArgs e)
		{
			ddlMethods.Enabled = true;

			FillMethods();
		}

		private void ddlMethods_SelectedIndexChanged(object sender, EventArgs e)
		{
			bOK.Enabled = true;
		}

		private void FillMethods()
		{
			// saves the cursor and sets the wait cursor
			Cursor previousCursor = Cursor.Current;
			Cursor.Current = Cursors.WaitCursor;

			try {
			// gets all public methods (instance + static)
 				MethodInfo[] methods = CustomDataSourceDesigner.GetType(_component.Site, TypeName).GetMethods(BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance | BindingFlags.FlattenHierarchy);
				ddlMethods.BeginUpdate();

				ddlMethods.Items.Clear();

				// adds the methods to the dropdownlist
				foreach (MethodInfo method in methods) {
					MethodItem methodItem = new MethodItem(method);
					ddlMethods.Items.Add(methodItem);
				}
			} finally {
				Cursor.Current = previousCursor;
				ddlMethods.EndUpdate();
			}
		}

		private void bOK_Click(object sender, EventArgs e)
		{
			// if the type has changed, save it
			if (String.Compare(TypeName, _component.TypeName, false) != 0) {
				TypeDescriptor.GetProperties(_component)["TypeName"].SetValue(_component, TypeName);
			}

			// if the select method has changed, save it
			if (String.Compare(SelectMethod, _component.SelectMethod, false) != 0) {
				TypeDescriptor.GetProperties(_component)["SelectMethod"].SetValue(_component, SelectMethod);
			}

			// if there is method selected, refresh the schema
			if (MethodInfo != null) {
				_designer.RefreshSchemaInternal(MethodInfo.ReflectedType, MethodInfo.Name, MethodInfo.ReturnType, true);
			}
		}

		#endregion
	}
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
Spain Spain
Manuel Abadia had his MS Degree in Computer Science (Univ. Murcia, Spain)

He is a Freelance Software Architect/Engineer and Trainer.

He sells his own components in his webpage (http://www.manuelabadia.com).

He was the Software Architect for the MoviTAP project that won the first prize in the Microsoft and Vodafone mobile web Services contest.

He has done some external work in companies like Namco America Inc. and Gaelco SA.

He has contributed to the MAME project (http://www.mamedev.com) for some years (and continues to do so eventually).

Comments and Discussions