No, unfortunately this isn't possible. While it's likely that given a particular data source that such a search would be fairly simple, doing it in a more generic way (as the BindingSource
would) is a little less transparent. For one, the syntax would be less than obvious. Here's a somewhat contrived solution:
public class Key
{
public string PropertyName {get; set;}
public object Value {get; set;}
}
public static int Find(this BindingSource source, params Key[] keys)
{
PropertyDescriptor[] properties = new PropertyDescriptor[keys.Length];
ITypedList typedList = source as ITypedList;
if(source.Count <= 0) return -1;
PropertyDescriptorCollection props;
if(typedList != null) // obtain the PropertyDescriptors from the list
{
props = typedList.GetItemProperties(null);
}
else // use the TypeDescriptor on the first element of the list
{
props = TypeDescriptor.GetProperties(source[0]);
}
for(int i = 0; i < keys.Length; i++)
{
properties[i] = props.Find(keys[i].PropertyName, true, true); // will throw if the property isn't found
}
for(int i = 0; i < source.Count; i++)
{
object row = source[i];
bool match = true;
for(int p = 0; p < keys.Count; p++)
{
if(properties[p].GetValue(row) != keys[p].Value))
{
match = false;
break;
}
}
if(match) return i;
}
return -1;
}
You can call it like this:
BindingSource source = // your BindingSource, obviously
int index = source.Find(
new Key { PropertyName = "PetType", Value = "Dog" },
new Key { PropertyName = "Gender", Value = "M" });
Bear in mind that for this to be usable, you really need a smarter comparison algorithm, but I'll leave that as an exercise to the reader. Checking for an implementation of IComparable
would be a good start. Nonetheless, the concept should carry through regardless of that particular point of implementation.
Note that this won't take advantage of any of the possible performance optimizations that might be implemented by the underlying data source, whereas the single column Find
would.