Plateforme Level Extreme
Abonnement
Profil corporatif
Produits & Services
Support
Légal
English
DataBinding
Message
 
À
25/03/2003 13:37:45
Information générale
Forum:
ASP.NET
Catégorie:
Autre
Titre:
Divers
Thread ID:
00769841
Message ID:
00770586
Vues:
16
Yeah, this is what I've been alluding to on a few posts that we've traded here <g>...

Here's what I've done (generic code at the end):

Create custom controls that have new properties:
ControlSourceObject (the parent obbject to bind to)
ControlSourceProperty (the property of that object to bind to)
BindingProperty (the property of the control to bind to)

So for example, I can bind anything to anything:

Objects (which you can't do with ASP.Net databinding)
DataRows (which you can't do with ASP.Net databindfing)
DataSets (which you can do)

For example (on a textbox):

ControlSourceObject = "Invoice.DataRow";
ControlSourceProperty = "InvNo";
BindingProperty = "Text"

Combobox:
ControlSourceObject = "Invoice.DataSet";
ControlSourceProperty = "wws_invoice.CountryId";
BindingProperty = "SelectedText"

This stuff binds to a business object but work the same if you bound to the dataset directly.

To do this you need to do a fair amount of work:

Subclass each control you want to bind
Use Reflection to figure out the control and datasource values
Use Reflection to swap values

but it will make life SO MUCH EASIER than it is now it's ridiculous.

In a Web Form this works great:
You set the 2 ControlSource Properties
I call a generic wwDataUtils.FormBindData to bind
I call a generic wwDataUtils.FormUnbindData to bind data back into the datasource

This process can be even more automated with a custom form subclass, but I actually like the idea of manually calling these methods because it gives me full control of when these actions occur - IOW they never occur by default.

I can't post everything here but the following are the key methods that handle binding a control and binding an entire Web form from the wwDataUtils class:
/// <summary>
/// Summary description for wwWebDataControlHelper.
/// </summary>
public class wwWebDataHelper
{

/// <summary>
/// Binds all databound controls on a WebForm page by calling their BindData methods.
/// </summary>
/// <param name="Container">the parent container (Page)</param>
public static void FormBindData(Page WebForm) 
{
	FormBindData((Control) WebForm, WebForm);
}

/// <summary>
/// Binds all databound controls on a WebForm page by calling their BindData methods.
/// </summary>
/// <param name="Container">the control to databind</param>
/// <param name="Form">the master container that contains the control (page)</param>
static void FormBindData(Control Container, Page WebForm) 
{
	// *** Drill through each control on the form
	foreach( Control loControl in Container.Controls)
	{
		// ** Recursively call down into any containers
		if (loControl.Controls.Count > 0)
			wwWebDataHelper.FormBindData(loControl, WebForm);

		// ** only work on those that support interface
		if (loControl is IwwWebDataControl ) 
		{
			IwwWebDataControl control = (IwwWebDataControl) loControl;

			try 
			{
				//*** Call the BindData method on the control
				control.GetType().InvokeMember("BindData",System.Reflection.BindingFlags.InvokeMethod,
					null,control, new object[1] { WebForm } );
			}
			catch(Exception) 
			{
				// *** Display Error info
				try 
				{
					///TODO: This must be adjusted for specific types of controls
					control.Text = "** Field binding Error **";
				}
				catch(Exception) {;} 
			}
		}
	}
				
}

public static BindingError[] FormUnbindData(Page WebForm) 
{
	
	BindingError[] Errors = null;
	FormUnbindData(WebForm,WebForm,ref Errors);
	return Errors;
}

static BindingError[] FormUnbindData(Control Container, Page WebForm, ref BindingError[] Errors) 
{
	
	// *** Drill through each of the controls
	foreach( Control loControl in Container.Controls)
	{
		// ** Recursively call down into containers
		if (loControl.Controls.Count > 0)
			FormUnbindData(loControl, WebForm,ref Errors);

		if (loControl is IwwWebDataControl ) 
		{
			IwwWebDataControl control = (IwwWebDataControl) loControl;

			try 
			{
				control.GetType().InvokeMember("UnbindData",System.Reflection.BindingFlags.InvokeMethod,
					null,control, new object[1] { WebForm } );
			}
			catch(Exception ex) 
			{
				// *** Display Error info
				try 
				{
					BindingError loError = new BindingError();
					if (wwUtils.Empty(control.BindingErrorMessage))
						loError.Message = "Invalid data format for " + loControl.ID;
					else
						loError.Message = control.BindingErrorMessage;
					
					loError.ErrorMsg = ex.Message;
					loError.Source = ex.Source;
					loError.StackTrace = ex.StackTrace;
					loError.ObjectName = loControl.ID;

					if (Errors == null) 
					{	
						Errors = new BindingError[1];
						Errors[0] = loError;
					}
					else
					{
						// *** Resize the array and assign Error
						int lnSize = Errors.GetLength(0);
						Array loTemp =  Array.CreateInstance(typeof(BindingError),lnSize + 1);
						Errors.CopyTo(loTemp,0);
						loTemp.SetValue(loError,lnSize);

						Errors = (BindingError[]) loTemp;
					}
				}
				catch(Exception) {;} 
			}
		}

	}
	return Errors;
}


public static string BindingErrorsToString(BindingError[] Errors) 
{
	// *** Optional Error Parsing
	if (Errors != null) 
	{
		string lcErrors = "";
		for (int x = 0; x < Errors.Length; x++) 
		{
			lcErrors = lcErrors + Errors[x].Message + "<br>";
		}
		if (!wwUtils.Empty(lcErrors))
			return  lcErrors;
	}

	return "";
}

/// <summary>
/// 
/// </summary>
/// <param name="WebPage"></param>
/// <param name="ActiveControl"></param>
/// <param name="ControlSourceObject"></param>
/// <param name="ControlSourceProperty"></param>
/// <param name="BindingProperty"></param>
public static void ControlBindData(Page WebPage, 
									Control ActiveControl,
									string ControlSourceObject,
									string ControlSourceProperty, 
			                        string BindingProperty) 
{
	try 
	{
		if (ControlSourceObject == null || ControlSourceObject.Length == 0 ||
			ControlSourceProperty == null || ControlSourceProperty.Length == 0)  
			return;

		object loControlSource = wwUtils.GetPropertyEx(WebPage,ControlSourceObject);
		if (loControlSource == null)
			return;

		object loValue;

		if (loControlSource is System.Data.DataSet) 
		{
			string lcTable = ControlSourceProperty.Substring(0,ControlSourceProperty.IndexOf("."));
			string lcColumn = ControlSourceProperty.Substring(ControlSourceProperty.IndexOf(".")+1);
			DataSet Ds = (DataSet) loControlSource;
			loValue = Ds.Tables[lcTable].Rows[0][lcColumn];
		}
		else if(loControlSource is System.Data.DataRow)
		{
			DataRow Dr = (DataRow) loControlSource;
			loValue = Dr[ControlSourceProperty];
		}
		else
		{
			loValue = wwUtils.GetPropertyEx(loControlSource,ControlSourceProperty);
		}

		/// *** Figure out the type of the control we're binding to
		object loBindValue = wwUtils.GetProperty(ActiveControl,BindingProperty);
		string lcControlSourceType = loBindValue.GetType().Name;

		if (loValue == null)
			if (lcControlSourceType == "String")
				wwUtils.SetProperty(ActiveControl,BindingProperty,"");
			else if (lcControlSourceType == "Boolean")
				wwUtils.SetProperty(ActiveControl,BindingProperty,false);
			else
				wwUtils.SetProperty(ActiveControl,BindingProperty,"");
		else 
		{
			///TODO: Fix Formatting here					
			if (lcControlSourceType == "Boolean") 
				wwUtils.SetProperty(ActiveControl,BindingProperty,loValue);
			else
				wwUtils.SetProperty(ActiveControl,BindingProperty,loValue.ToString());
		}
	}
	catch(Exception) 
	{
		throw(new Exception("Can't bind " + ActiveControl.ID  + " to " + 
			ControlSourceObject + "." + 
			ControlSourceProperty));
	}
}


/// <summary>
/// Unbinds control properties back into the control source
/// </summary>
/// <param name="WebPage">The WebForm Page object</param>
/// <param name="ActiveControl">The control to unbind</param>
/// <param name="ControlSourceObject"></param>
/// <param name="ControlSourceProperty"></param>
/// <param name="BindingProperty"></param>
public static void ControlUnbindData(Page WebPage, 
										Control ActiveControl,
									string ControlSourceObject,
									string ControlSourceProperty, 
									string BindingProperty) 
{
	if (ControlSourceObject == null || ControlSourceObject.Length == 0 ||
		ControlSourceProperty == null || ControlSourceProperty.Length == 0)  
		return;

	object loControlSource = wwUtils.GetPropertyEx(WebPage,ControlSourceObject);
	if (loControlSource == null)
		return;

	// Retrieve the new value from the control
	object loValue = wwUtils.GetPropertyEx(ActiveControl,BindingProperty);

	// Try to retrieve the type of the ControlSourceProperty
	string lcControlSourceType;
	string lcDataColumn = null;
	string lcDataTable = null;

	if (loControlSource is System.Data.DataSet) 
	{
		lcDataTable = ControlSourceProperty.Substring(0,ControlSourceProperty.IndexOf("."));
		lcDataColumn = ControlSourceProperty.Substring(ControlSourceProperty.IndexOf(".")+1);
		DataSet Ds = (DataSet) loControlSource;
		lcControlSourceType = Ds.Tables[lcDataTable].Columns[lcDataColumn].DataType.Name;
	}
	else if(loControlSource is System.Data.DataRow)
	{
		DataRow Dr = (DataRow) loControlSource;
		lcControlSourceType = Dr.Table.Columns[ControlSourceProperty].DataType.Name;
	}
	else 
	{
		// *** It's an object property
		MemberInfo[] loInfo = loControlSource.GetType().GetMember(ControlSourceProperty);
		if (loInfo[0].MemberType.ToString() == "Field") 
		{
			FieldInfo loField = (FieldInfo) loInfo[0];
			lcControlSourceType = loField.FieldType.Name;
		}
		else
		{
			PropertyInfo loField = (PropertyInfo) loInfo[0];
			lcControlSourceType = loField.PropertyType.Name;
		}
	}

	/// Retrieve the value
	object loAssignedValue;

	if ( lcControlSourceType == "String")
		loAssignedValue = loValue;
	else if (lcControlSourceType  == "Int16")  
		loAssignedValue = Convert.ToInt16(loValue);				
	else if (lcControlSourceType  == "Int32")  
		loAssignedValue = Convert.ToInt32(loValue);				
	else if (lcControlSourceType  == "Int64")  
		loAssignedValue = Convert.ToInt64(loValue);				
	else if (lcControlSourceType  == "Byte")  
		loAssignedValue = Convert.ToByte(loValue);				
	else if (lcControlSourceType  == "Decimal")  
		loAssignedValue = Convert.ToDecimal(loValue);				
	else if (lcControlSourceType  == "Double")  
		loAssignedValue = Convert.ToDouble(loValue);				
	else if (lcControlSourceType  == "Boolean") 
	{
		loAssignedValue = loValue;
//				lcValue = lcValue.ToLower();
//				if (lcValue == "on" || lcValue == "true" || lcValue == "1") 
//					loAssignedValue = true;
//				else
//					loAssignedValue = false;
	}
	else if (lcControlSourceType  == "DateTime")  
		loAssignedValue = Convert.ToDateTime(loValue);				
	else  // Not HANDLED!!!
		throw(new Exception("Field Type not Handled by Data unbinding"));

	/// Write the value back to the underlying object/data item
	if (loControlSource is System.Data.DataSet) 
	{
		DataSet Ds = (DataSet) loControlSource;
		Ds.Tables[lcDataTable].Rows[0][lcDataColumn] = loAssignedValue;
	}
	else if(loControlSource is System.Data.DataRow) 
	{
		DataRow Dr = (DataRow) loControlSource;
		Dr[ControlSourceProperty] = loAssignedValue;
	}	
	else
		wwUtils.SetPropertyEx(loControlSource,ControlSourceProperty,loAssignedValue);
}


}
Enjoy <g>,
+++ Rick ---

West Wind Technologies
Maui, Hawaii

west-wind.com/
West Wind Message Board
Rick's Web Log
Markdown Monster
---
Making waves on the Web

Where do you want to surf today?
Précédent
Suivant
Répondre
Fil
Voir

Click here to load this message in the networking platform