//  FieldValueAtIndex
//
//  PURPOSE:  This function determines the value of a named field within some row within
//		this DataSet.  The tricky part is determining which row is desired.  Consider an
//		example.  Suppose we have a page containing 3 DataSets:  ds1, ds2 and ds3.  This
//		page might contain a DataGrid, g1, bound to ds1.  Within the DataGrid may be
//		with a TemplateColumn containing a Repeater, r1, bound to ds2.  Within the Repeater
//		might be an ItemTemplate containing ds1.FieldValue("foo", Container) as well as
//		ds2.FieldValue("bar", Container).  Outside the whole DataGrid might be another
//		Repeater, r2, bound to ds1 containing an ItemTemplate containing
//		ds1.FieldValue("foo", Container) and ds3.FieldValue("xyz", Container).  We can
//		diagram this as:
//
//		DataSet ds1
//		DataSet ds2
//		DataSet ds3
//
//		DataGrid g1 bound to ds1
//			TemplateColumn
//				ItemTemplate
//					Repeater r1 bound to ds2
//						ItemTemplate
//							ds1.FieldValue("foo", Container)  [use the row in ds1 that g1 is currently processing]
//							ds2.FieldValue("bar", Container)  [use the row in ds2 that r1 is currrently processing]
//
//		Repeater r2 bound to ds1
//			ds1.FieldValue("foo", Container) [use the row in ds1 that r2 is currently processing]
//			ds3.FieldValue("xyz", Container) [use the 0th row in ds3]
//		
//		The challenge presented to this method is to resolve the field values according to the
//		description shown above in square brackets.
//
public string FieldValueAtIndex(int Index, string FieldName, System.Web.UI.Control Container)
{
	string strReturn = "";  // contains the field value that we eventually resolve to

	try
	{
		//  Make some objects so we can get their types to use later in comparisons.

		System.Web.UI.WebControls.Repeater theRepeater = new System.Web.UI.WebControls.Repeater();
		System.Web.UI.WebControls.DataList theDataList = new System.Web.UI.WebControls.DataList();
		System.Web.UI.WebControls.DataGrid theDataGrid = new System.Web.UI.WebControls.DataGrid();

		System.Web.UI.WebControls.RepeaterItem repeaterItemContainer = new System.Web.UI.WebControls.RepeaterItem(0, ListItemType.Item);
		System.Web.UI.WebControls.DataListItem dataListItemContainer = new System.Web.UI.WebControls.DataListItem(0, ListItemType.Item);
		System.Web.UI.WebControls.DataGridItem dataGridItemContainer = new System.Web.UI.WebControls.DataGridItem(0, 0, ListItemType.Item);

		Type repeaterType = theRepeater.GetType();
		Type dataListType = theDataList.GetType();
		Type dataGridType = theDataGrid.GetType();
		 
		Type repeaterItemType = repeaterItemContainer.GetType();
		Type dataListItemType = dataListItemContainer.GetType();
		Type dataGridItemType = dataGridItemContainer.GetType();

		theRepeater = null;
		theDataList = null;
		theDataGrid = null;

		//  We will now figure out what control (Repeater, DataList or DataGrid) this DataSet
		//  has been bound to.  Later we can figure out what row that control is presently
		//  processing.

		Control theParent = null;

		if (Container != null)
		{
			theParent = Container.Parent;
			while (theParent != null)
			{
				if (repeaterType.IsInstanceOfType(theParent))
				{
					theRepeater = (System.Web.UI.WebControls.Repeater)theParent;
					if (theRepeater.DataSource == this.DefaultView)
					{
						break;
					}
				}
				else if (dataListType.IsInstanceOfType(theParent))
				{
					theDataList = (System.Web.UI.WebControls.DataList)theParent;
					if (theDataList.DataSource == this.DefaultView)
					{
						break;
					}
				}
				else if (dataGridType.IsInstanceOfType(theParent))
				{
					theDataGrid = (System.Web.UI.WebControls.DataGrid)theParent;
					if (theDataGrid.DataSource == this.DefaultView)
					{
						break;
					}
				}

				theParent = theParent.Parent;
			}

			//  Finding the control that this DataSet is bound to isn't enough.  
			//  We have to get the field value of a the right record within
			//  that DataSet.  That is, we have to find the row in that DataSet
			//  that the Repeater or DataList or DataGrid is currently processing.

			if (theParent != null)
			{
				Control candidateBindingContainer = Container;
				while (candidateBindingContainer != null)
				{
					while ((candidateBindingContainer == null) ||
						   ((!repeaterItemType.IsInstanceOfType(candidateBindingContainer)) &&
							(!dataListItemType.IsInstanceOfType(candidateBindingContainer)) &&
							(!dataGridItemType.IsInstanceOfType(candidateBindingContainer))))
					{
						try
						{
							candidateBindingContainer = candidateBindingContainer.BindingContainer;
						}
						catch
						{
							candidateBindingContainer = null;
						}
					}

					if (candidateBindingContainer != null)
					{
						if (repeaterType.IsInstanceOfType(theParent))
						{
							if ((candidateBindingContainer.Parent != null) &&
							    (candidateBindingContainer.Parent == theRepeater))
							{
								strReturn = ((DataView)(theRepeater.DataSource))[((RepeaterItem)candidateBindingContainer).ItemIndex][FieldName].ToString();
								return strReturn;
							}
						}
						else if (dataListType.IsInstanceOfType(theParent))
						{
							if ((candidateBindingContainer.Parent != null) &&
							    (candidateBindingContainer.Parent == theDataList))
							{
								strReturn = ((DataView)(theDataList.DataSource))[((DataListItem)candidateBindingContainer).ItemIndex][FieldName].ToString();
								return strReturn;
							}
						}
						else if (dataGridType.IsInstanceOfType(theParent))
						{
							if ((candidateBindingContainer.Parent != null) &&
								(candidateBindingContainer.Parent.Parent != null) &&
							    (candidateBindingContainer.Parent.Parent == theDataGrid))
							{
								strReturn = ((DataView)(theDataGrid.DataSource))[((DataGridItem)candidateBindingContainer).ItemIndex][FieldName].ToString();
								return strReturn;
							}
						}

						candidateBindingContainer = candidateBindingContainer.Parent;
					}
				}
			}
		}

		//  If we haven't found the parent control then we must fall back on something
		//  safe:  simply access the field value at the given index.

		if (theParent == null)
		{
			strReturn = DefaultView[Index][FieldName].ToString();
		}
	}
	catch
	{
	}

	return strReturn.Trim();
}