Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Languages / C# / February 2008

Tip: Looking for answers? Try searching our database.

Abstract event

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Andrus - 16 Feb 2008 17:34 GMT
public delegate void EntitySelectedEventHandler(EntityBase selectedEntity);

abstract internal partial class BrowseForm : Form {
public abstract event EntitySelectEventHandler EntitySelect { add;}
}

causes error: An add or remove accessor must have a body

but

public abstract EntitySelectedEventHandler EntitySelected { set; }

works OK.

Why events cannot be abstract ? How to create abstract events ?

Andrus.
Jeroen Mostert - 16 Feb 2008 20:38 GMT
> 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.
Jon Skeet [C# MVP] - 16 Feb 2008 20:40 GMT
> 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


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.