First I'd like to thank mike and Goody. I've gotten DataParameter to work for me using essentially what's on this post, and it's solved my problem. I think this is an important update to NetTiers.
I have a few points however:
- I think the intent of DataParameter was to build a where clause for GetPaged. I don't see any reason why it wouldn't work for this purpose, except...
- ... _dataSource = control.FindControl would never work, since control in the context of Evaluate is the DataSource that contains this DataParameter. There's no way that one DataSource can contain another DataSource, right?
From #1, I think the changes suggested in this post would be changing the intent of the control. I think you should be able to specify the type of return: either a WhereClause expression like it does currently, or a single value as suggested above. I'd suggest a new bool property (I don't know, UseWhereClauseFormat?) that would toggle this.
From point #2, it seems like this parameter has never worked. Should changes we make to DataParameter be considered a "Breaking Change" in that case?
For finding the DataSource control, I suggest that even Page.Form.FindControl(DataSourceID) is a bad move: What if the target data source is in a user control? control.NamingContainer.FindControl would be better. Unfortunately, that doesn't work if the parameter's DataSource is inside a FormView and the target DataSource is outside of it (that's a problem I ran into). The solution that eventually worked for me was to add this function to FormUtilBase:
------
/// <summary>
/// Searches for the specified control id in the nearest INamingContainer
/// (searching outward from the specified control).
/// </summary>
/// <param name="control">The <see cref="Control"/> at which to begin the search.</param>
/// <param name="controlId">The id parameter value.</param>
/// <returns></returns>
public static Control FindNearestControl(Control control, String controlId)
{
Control found = null;
if ( control != null )
{
if (control is INamingContainer)
{
found = control.FindControl(controlId);
}
if (found == null)
{
found = FindNearestControl(control.NamingContainer, controlId);
}
}
return found;
}
------
And my evaluate function looks like this:
------
protected override Object Evaluate(HttpContext context, Control control)
{
String value = String.Empty;
if ( _dataSource == null && control != null )
{
_dataSource = FormUtil.FindNearestControl(control, DataSourceID) as IListDataSource;
}
if ( _dataSource != null )
{
IEnumerable entityList = _dataSource.GetEntityList();
if ( entityList != null )
{
IList list = EntityUtil.GetEntityList(entityList);
Object temp;
foreach ( Object item in list )
{
temp = EntityUtil.GetPropertyValue(item, PropertyName);
if ( temp != null )
{
value = temp.ToString();
break;
}
}
}
}
return value;
}
------
This of course only returns the single value. It should be simple to add the old behavior depending on a new bool property. Anyone have thoughts on this approach? If you guys like it, i'd be happy to offer it as a patch.
Thanks!