> public delegate void EntitySelectedEventHandler(EntityBase selectedEntity);
>
> abstract internal partial class BrowseForm : Form {
> public abstract event EntitySelectEventHandler EntitySelect { add;}
> }
An event can't have only an add-accessor, whether it's abstract or not. If
the event is not abstract, the compiler will auto-generate these for you,
which is why you usually don't declare them. You can do the following:
public abstract event EntitySelectEventHandler EntitySelect;
However, even that is not how it's usually done, since there is seldom a
point to forcing derived classes to implement the event themselves. This is
the usual pattern:
class A {
public event EntitySelectEventHandler EntitySelect;
protected virtual void OnEntitySelect(EntitySelectedEventArgs e) {
if (EntitySelect != null) EntitySelect(this, e);
}
// All internal event generators use the On... method instead of invoking
the event directly
}
class B : A {
public override void OnEntitySelect(EntitySelectedEventArgs e) {
// Custom processing before the attached event handlers fire
base.OnEntitySelect(e);
// Custom processing after the attached event handlers have fired
}
}
If you really want to, you can define the add and remove accessors to call
virtual methods as well, so the child classes can override them, but this is
rarely useful.

Signature
J.
Andrus - 17 Feb 2008 11:00 GMT
Jeroen,
> However, even that is not how it's usually done, since there is seldom a
> point to forcing derived classes to implement the event themselves.
...
> If you really want to, you can define the add and remove accessors to call
> virtual methods as well, so the child classes can override them, but this
> is rarely useful.
I'm implementing winforms modeless picklist.
Picklist form contains picklist grid which raises EntitySelected event when
row is selected:
sealed class Grid<T> where T: EntityBase : BaseGrid {
internal event EntitySelectedEventHandler EntitySelected;
/// <summary>
/// Called when entity is selected by enter or by double click.
/// </summary>
/// <returns>true if event handler is present and event raised</returns>
bool OnEntitySelected() {
if (EntitySelected == null) return false;
T entityTmp = memoryCache.RetrieveElement(CurrentCell.RowIndex);
if (entityTmp == null)
// row has disappeared, some other user has changed data
return false;
EntitySelected(entityTmp);
return true;
}
Picklist form also implements EntitySelected event by forwarding it to
grid:
sealed class BrowseForm<T> where T: EntityBase : BrowseForm {
Grid<T> grid;
internal override event EntitySelectedEventHandler EntitySelect {
add {
grid.EntitySelected += value;
selectToolStripButton.Visible = true;
}
remove {
grid.EntitySelected -= value;
selectToolStripButton.Visible = false;
}
...
Combobox in main form invokes picklist form by using
class MyComboBox : ComboBox {
BrowseForm f;
protected override void OnDropDown(System.EventArgs e) {
f = new BrowseForm<Customer>();
f.EntitySelect += OnEntitySelected;
}
void OnEntitySelected(EntityBase selected) {
f.Close();
SelectedItem = selected;
Focus();
}
}
Questions:
1. Is this best design pattern for this ?
2. Picklist form sends selected event only to single form always, not to
multiple recipients for which event patter is designed. If main form is
closed before picklist form, event handler seems to be removed
automatically. So it is no need to implement remove. However event
implementation requires remove to be implemented.
Is it resonable to use delegate instead of event and implement only set
accessor ?
Andrus.
> public delegate void EntitySelectedEventHandler(EntityBase selectedEntity);
>
[quoted text clipped - 11 lines]
>
> Why events cannot be abstract ? How to create abstract events ?
Events can be abstract, but you can't specify just the add part. An
event *always* has an add and a remove - you can't have one without the
other. Compare this with properties, where you can definitely have a
write-only or a read-only property.
Remove the "{ add; }" bit and it will compile okay.

Signature
Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
World class .NET training in the UK: http://iterativetraining.co.uk