mick said:
Thanks for that. Got a question about BindingList<> now. How the hell do you find
an item in it?
This appears to be a completely different question, having nothing to do
with serialization. If so, IMHO it belongs in a completely new message
topic.
That said…
[...]
Now assume I have the name and I want to find the object with that name in the list-
how do I do that?
myList.Find("Some name") // equiv. of this
Do I have to do a foreach myself for every search?
No, not necessarily. If "MyItem" is a simple container class,
inexpensive to instantiate and implementing IComparable<T>, then you can
using BindingList.IndexOf():
MyItem item = new MyItem("Some name", 5);
int index = myList.Find(item);
The "index" variable gets the index of another MyItem instance in the
list that compares equal to the one you pass in. If it's not found, the
result is -1.
The BindingList class also provides an implementation of IBindingList,
which has a Find() method. It can be a bit awkward to use, but under
the right circumstances it could be appropriate. Assuming your "MyItem"
class has a public Name property:
PropertyDescriptor desc =
TypeDescriptor.GetProperties(typeof(MyItem)).Find("Name", false);
int index = ((IBindingList)myList).Find(desc, "Some name");
The above uses the component model classes to generate a description of
your type and then search for it. Again, -1 is returned if the element
isn't present.
In either case, you can get the actual object in the list just by
accessing it via the returned index.
Finally, you can use the Enumerable extension methods. There are
actually a variety of useful options, depending on your exact needs.
But, here's an example that is reasonably close to the above (again,
assuming there's a "Name" property):
MyItem item = myList
.Cast<MyItem>()
.FirstOrDefault(x => x.Name == "Some name");
Note that because BindingList<T> only implements IEnumerable and not
IEnumerable<T>, you first have to use the Cast<T>() method. Then the
FirstOrDefault() method allows you to provide a predicate delegate to do
the actual comparison on each item. In this case, I used a lambda
expression, but you could use a plain anonymous method:
MyItem item = myList
.Cast<MyItem>()
.FirstOrDefault(delegate(MyItem x)
{
return x.Name == "Some name";
});
Or even a named method:
MyItem item = myList
.Cast<MyItem>()
.FirstOrDefault(CompareName);
where:
bool CompareName(MyItem x)
{
return x.Name == "Some name";
}
Noting, of course, that everywhere I hard-coded "Some name", you can
just as easily use any other expression for comparison.
The FirstOrDefault() method will return the default value for the type
if the item isn't found ("null" for reference types). If you know the
item will be found, or want an exception if it's not, you can just call
First() instead.
Hope that helps.
Pete