public EventDescriptorCollection GetEvents(object component, Attribute[] attributes, bool noFilter) {
// Worst case event collision scenario is two sets of events. Much cheaper than
// a constant lock.
//
if (this.events == null) {
this.events = new EventDescriptorCollection(new MemberList(this).GetEvents(), true);
}
EventDescriptorCollection filteredEvents = events;
if (component is IComponent) {
ITypeDescriptorFilterService tf = (ITypeDescriptorFilterService)GetService(component, typeof(ITypeDescriptorFilterService));
if (!noFilter && tf != null) {
// The component's site is interested in filtering events. See if we
// have filtered them before. If so, then we're done. Otherwise we
// need to filter.
//
IDictionaryService ds = (IDictionaryService)GetService(component, typeof(IDictionaryService));
if (ds != null) {
EventDescriptorCollection savedEvents = null;
lock(ds) {
savedEvents = (EventDescriptorCollection)ds.GetValue(typeof(EventDescriptorCollection));
}
if (savedEvents != null) {
// Check that the filter that was used to create these attributes is the same
// filter we currently have. People may replace the filter, and if we do
// we must refresh the cache.
//
object savedFilter = ds.GetValue(typeof(ITypeDescriptorFilterService));
if (savedFilter == null || savedFilter == tf) {
filteredEvents = savedEvents;
}
}
}
if (filteredEvents == events) {
Hashtable filterTable = new Hashtable(events.Count);
if (events != null) {
foreach (EventDescriptor ev in events) {
filterTable[ev.Name] = ev;
}
}
bool cache = tf.FilterEvents((IComponent)component, filterTable);
EventDescriptor[] temp = new EventDescriptor[filterTable.Values.Count];
filterTable.Values.CopyTo(temp, 0);
filteredEvents = new EventDescriptorCollection(temp, true);
if (ds != null && cache) {
lock(ds) {
ds.SetValue(typeof(EventDescriptorCollection), filteredEvents);
ds.SetValue(typeof(ITypeDescriptorFilterService), tf);
}
}
}
}
}
if (attributes != null && attributes.Length > 0) {
ArrayList list = new ArrayList(filteredEvents);
FilterMembers(typeof(EventDescriptor), list, attributes);
EventDescriptor[] temp = new EventDescriptor[list.Count];
list.CopyTo(temp, 0);
filteredEvents = new EventDescriptorCollection(temp, true);
}
return filteredEvents;
}