Skip to main content

...

....

C# Tutorial - Event Accessors [Beginner]


Events in C# can be weird little beasts. We have talked about how to use and create them before, but really that article only scratches the surface. At first events seem like a special construct, all by themselves in the C# world. But then, after a while (And after you learn about delegates), you realize that all they really are are multicast delegates. But then, even longer after that, you realize that while it may be just a multicast delegate underneath, there are a couple things on top that make the C# event unique.

Or at least, that is the progression of knowledge that happened for me. And today we are going to talk about what triggered my transition to that third state of thinking about events - event accessors. It turns out that as a .NET programmer you have much more control over events then you might think at first, because you can actually override the add and removal operators for an event. Those += and -= operators? You can control what actually happens when they are used.

So you are probably wondering what the syntax is to do this. It is actually very similar to a syntax structure that you are probably already quite familiar with - the property get/set syntax. The main difference is that in this case we are not getting/setting, we are adding/removing:
public event EventHandler MyEvent
{
  add
  {

  }

  remove
  {

  }
}
 
So in this case, using the += operator on MyEvent would enter the add block, and the -= operator would enter the remove block. Now, obviously in this case, nothing would happen, because we don't do anything in either case.

So lets take a look at some code that duplicates the normal event behavior:
class MyClass
{
  private event EventHandler MyPrivateEvent;

  public event EventHandler MyEvent
  {
    add
    {
      MyPrivateEvent += value;
    }
    remove
    {
      MyPrivateEvent -= value;
    }
  }
}
 
Again, very similar to the get/set property definition, where value ends up holding what was passed into the property. And in this case, value will always be of type EventHandler. Essentially, this extends to events the standard object oriented abstraction of always having public getters and setters for a private member field.

That code isn't really very interesting, because it implements the exact behavior of the standard C# event. But there are a couple ways it can come in handy. One common one, I have found, is for debugging purposes - you can easily throw some debugging info in the add and remove accessors:
class MyClass
{
  private event EventHandler MyPrivateEvent;

  public event EventHandler MyEvent
  {
    add
    {
      Debug.WriteLine("Attaching To MyEvent");
      MyPrivateEvent += value;
    }
    remove
    {
      MyPrivateEvent -= value;
      Debug.WriteLine("Detaching From MyEvent");
    }
  }
}
 
And of course you can do whatever else you want to do in add and remove accessors - maybe initialize some other code, maybe not even attach the event at all in certain cases.

One of the odder possibilities with these accessors is to not actually use an event as the underlying delegate holding structure. That might sound kind of weird, but it should make sense when you look at the code:
class MyClass
{
  private List<EventHandler> MyEventStorage = new List<EventHandler>();

  public event EventHandler MyEvent
  {
    add
    {
      MyEventStorage.Add(value);
    }
    remove
    {
      MyEventStorage.Remove(value);
    }
  }

  //And with this technique, you can have
  //stuff like this
  public void ClearAttached()
  {
    MyEventStorage.Clear();
  }
}
 
I have never had reason to use this manner of event delegate storage, but I have a feeling it could come in handy if you wanted to be able to actually work with the list of event hooks. Take, for instance, the ClearAttached method - the equivalent code using a normal event object would actually be somewhat complicated. Granted, the code to fire the list of events would be a little more complex then the normal event firing code, but hey, there are always trade offs.

And that is all I have on event accessors - you can check out Microsoft's docs for other examples of why this syntax is useful.

Comments

Popular posts from this blog

C# Snippet - Shuffling a Dictionary [Beginner]

Randomizing something can be a daunting task, especially with all the algorithms out there. However, sometimes you just need to shuffle things up, in a simple, yet effective manner. Today we are going to take a quick look at an easy and simple way to randomize a dictionary, which is most likely something that you may be using in a complex application. The tricky thing about ordering dictionaries is that...well they are not ordered to begin with. Typically they are a chaotic collection of key/value pairs. There is no first element or last element, just elements. This is why it is a little tricky to randomize them. Before we get started, we need to build a quick dictionary. For this tutorial, we will be doing an extremely simple string/int dictionary, but rest assured the steps we take can be used for any kind of dictionary you can come up with, no matter what object types you use. Dictionary < String , int > origin = new Dictionary < string , int >();

C# WPF Printing Part 2 - Pagination [Intermediate]

About two weeks ago, we had a tutorial here at SOTC on the basics of printing in WPF . It covered the standard stuff, like popping the print dialog, and what you needed to do to print visuals (both created in XAML and on the fly). But really, that's barely scratching the surface - any decent printing system in pretty much any application needs to be able to do a lot more than that. So today, we are going to take one more baby step forward into the world of printing - we are going to take a look at pagination. The main class that we will need to do pagination is the DocumentPaginator . I mentioned this class very briefly in the previous tutorial, but only in the context of the printing methods on PrintDialog , PrintVisual (which we focused on last time) and PrintDocument (which we will be focusing on today). This PrintDocument function takes a DocumentPaginator to print - and this is why we need to create one. Unfortunately, making a DocumentPaginator is not as easy as

C# WPF Tutorial - Implementing IScrollInfo [Advanced]

The ScrollViewer in WPF is pretty handy (and quite flexible) - especially when compared to what you had to work with in WinForms ( ScrollableControl ). 98% of the time, I can make the ScrollViewer do what I need it to for the given situation. Those other 2 percent, though, can get kind of hairy. Fortunately, WPF provides the IScrollInfo interface - which is what we will be talking about today. So what is IScrollInfo ? Well, it is a way to take over the logic behind scrolling, while still maintaining the look and feel of the standard ScrollViewer . Now, first off, why in the world would we want to do that? To answer that question, I'm going to take a an example from a tutorial that is over a year old now - Creating a Custom Panel Control . In that tutorial, we created our own custom WPF panel (that animated!). One of the issues with that panel though (and the WPF WrapPanel in general) is that you have to disable the horizontal scrollbar if you put the panel in a ScrollV