views:

517

answers:

4

Hi,

How can I launch an event that has accessors like this :

public event EventHandler CanExecuteChanged
 {
   add
   {
     CommandManager.RequerySuggested += value;
   }
   remove
   {
     CommandManager.RequerySuggested -= value;
   }
 }

If it were a normal event I would launch it by:

CanExecuteChanged(sender, EventArgs..).

But here it doesn't work - I can only do

CanExecuteChanged +=..

to attach a method do the event - but I can't Launch it.

Also some documentation on the subject would be appreciated. Thanks.

EDIT The event is from class implementing ICommand in WPF. there's nothing more to show :). And no - the CommandManager.RequerySuggested(this, EventArgs.Empty); doesn't work.

EDIT2 Not sure what to say - Jon's example should have worked yet even if the add method is called correctly - when I try to call the event - it's null :|. I probably will drop events with accessors.

A: 
You've got to invoke the underlying events directly. In your case, it looks as though this would be:
CommandManager.RequerySuggested(sender, EventArgs.…)

/EDIT: Ok, I didn't notice that CommandManager is a framework class. In this case, you obviously don't want to do what I've proposed. Jon's solution is to the point: You've got to keep track of your own event and invoke that (e.g. as a delegate). In keeping with Jon's example, invocation would look like this:

canExecuteChanged(sender, EventArgs.Empty);
Konrad Rudolph
+3  A: 

I think you have events confused with delegates. Only the class exposing the event can raise it... Others can only subscribe-unsubscribe to it. If you are invoking the event from within the class declaring the event, it should work like a regular delegate.

The best page I could find on Events vs Delegates. Read up..

Can you post a bigger snippet.. something seems amiss..

Killer Update

I think I finally see your problem and how to solve it. Short Answer: It does not know the name of delegate to invoke if you write your own accessors. If you don't.. the compiler adds the private delegate of known name and hence is able to invoke it

This code snippet shows what I mean. This MSDN article showed me the light. Great question dude.. I lost 30 mins. Upvoted :)

public class Hash1 
    {

        private EventHandler myHomeMadeDelegate;
        public event EventHandler FancyEvent
        {
            add
            {
                //myDelegate += value;
                myHomeMadeDelegate = (EventHandler)Delegate.Combine(myHomeMadeDelegate, value);
            }
            remove
            {
                //myDelegate -= value;
                myHomeMadeDelegate = (EventHandler)Delegate.Remove(myHomeMadeDelegate, value);
            }
        }
        public event EventHandler PlainEvent;


        public Hash1()
        {
            FancyEvent += new EventHandler(On_Hash1_FancyEvent);
            PlainEvent += new EventHandler(On_Hash1_PlainEvent);

            // FancyEvent(this, EventArgs.Empty);  //won't work:What is the backing delegate called? I don't know
            myHomeMadeDelegate(this, EventArgs.Empty); // Aha!
            PlainEvent(this, EventArgs.Empty);
        }

        void On_Hash1_PlainEvent(object sender, EventArgs e)
        {
            Console.WriteLine("Bang Bang!");
        }

        void On_Hash1_FancyEvent(object sender, EventArgs e)
        {
            Console.WriteLine("Bang!");
        }
}
Gishu
Damn .. I actually found that article myself but it didn't had enough code snippets :) so I move along .Also, Jon explained pretty much the same thing only shorter :). But thanks for going in more detail.Upvoted :P
sirrocco
+3  A: 

That event is just subscribing to and unsubscribing from another event. If you want your subscribers (and only your subscribers - not separate ones to the other event) to be invoked, you'll need to keep hold of your subscribers separately. For instance, you could change the code to something like:

private EventHandler canExecuteChanged;

public event EventHandler CanExecuteChanged
{
    add
    {
        CommandManager.RequerySuggested += value;
        canExecuteChanged += value;
    }
    remove
    {
        CommandManager.RequerySuggested -= value;
        canExecuteChanged -= value;
    }
}
Jon Skeet
+1  A: 

Ok, I found that if I want to trigger that event you have to do :

CommandManager.InvalidateRequerySuggested();.
sirrocco