Delegate.CreateDelegate causes argumentexception

A

Andrus

I tried to attach Event handler to dynamically created
ObservableCollection but got ArgumentException in Delegate.CreateDelegate()
shown in comment.

How to fix ?

Andrus.

public event EventHandler ModifiedsChanged;
public IList Modifieds;

void AddEvent( Type objectType ) {

Type listType = typeof(ObservableCollection<>).MakeGenericType(new[] {
objectType });
Modifieds = (IList)Activator.CreateInstance(listType);
EventInfo eInfo = listType.GetEvent("CollectionChanged");
var mi = GetType().GetMethod("NotifyCollectionChanged",
BindingFlags.NonPublic | BindingFlags.Instance);

// ArgumentException: Error binding to target method.
var del = Delegate.CreateDelegate(eInfo.EventHandlerType, mi);
eInfo.AddEventHandler(Modifieds, del);
}


void NotifyCollectionChanged(object sender, NotifyCollectionChangedEventArgs
e) {
if (ModifiedsChanged != null)
ModifiedsChanged(this, EventArgs.Empty);
}
 
P

Peter Duniho

I tried to attach Event handler to dynamically created
ObservableCollection but got ArgumentException in
Delegate.CreateDelegate() shown in comment.

How to fix ?

Impossible to say unless you post a concise-but-complete code example that
reliably demonstrates the problem. But, I'd guess that the fact that
you're not providing an instance to go with the method is causing the
issue. The CreateDelegate() overload you're using is for static methods
only.

Pete
 
T

Tom Spink

Andrus said:
I tried to attach Event handler to dynamically created
ObservableCollection but got ArgumentException in Delegate.CreateDelegate()
shown in comment.

How to fix ?

Andrus.

public event EventHandler ModifiedsChanged;
public IList Modifieds;

void AddEvent( Type objectType ) {

Type listType = typeof(ObservableCollection<>).MakeGenericType(new[] {
objectType });
Modifieds = (IList)Activator.CreateInstance(listType);
EventInfo eInfo = listType.GetEvent("CollectionChanged");
var mi = GetType().GetMethod("NotifyCollectionChanged",
BindingFlags.NonPublic | BindingFlags.Instance);

// ArgumentException: Error binding to target method.
var del = Delegate.CreateDelegate(eInfo.EventHandlerType, mi);
eInfo.AddEventHandler(Modifieds, del);
}


void NotifyCollectionChanged(object sender, NotifyCollectionChangedEventArgs
e) {
if (ModifiedsChanged != null)
ModifiedsChanged(this, EventArgs.Empty);
}

Hello Andrus,

The problem is you're trying to attach an instance method to the event
handler, and you're not supplying the runtime with an object reference.

You need to change the CreateDelegate call to this:

///
CreateDelegate(eInfo.EventHandlerType, this, "NotifyCollectionChanged");
///

And you can scrap the "var mi = ..." line.

Hope this helps.
-- Tom
 
T

Tom Spink

Tom said:
Hello Andrus,

The problem is you're trying to attach an instance method to the event
handler, and you're not supplying the runtime with an object reference.

Alternatively, if you don't need dynamic specification of the handler
method, you could scrap all that CreateDelegate jazz altogether, and
just do this:

///
eInfo.AddEventHandler(Modifieds, new
NotifyCollectionChangedEventHandler(NotifyCollectionChanged));
///

-- Tom
 
A

Andrus

Tom,
Alternatively, if you don't need dynamic specification of the handler
method, you could scrap all that CreateDelegate jazz altogether, and
just do this:

Thank you. I simplified it even more:

eInfo.AddEventHandler(Modifieds, new
NotifyCollectionChangedEventHandler((s, e) =>
{
if (ModifiedsPropertyChanged != null)
ModifiedsPropertyChanged(this, EventArgs.Empty);
}));

Sometimes .NET allows to use lambda expression directly, but it seems that
in this case new NotifyCollectionChangedEventHandler(
constructor is required for unknown reason.

Andrus
 
P

Peter Duniho

[...]
Sometimes .NET allows to use lambda expression directly, but it seems
that in this case new NotifyCollectionChangedEventHandler(
constructor is required for unknown reason.

In order to avoid the "new", the compiler needs some way to infer the type
of the anonymous method the lambda expression represents. Often, this
inference can come from the target of the expression, either a variable
assignment or a method argument.

But in this case, the method argument has the abstract type Delegate.
There's no way to infer a concrete type in that context.

Strictly speaking, you still don't need the "new". You can provide the
necessary inferential information by casting the lambda to the desired
type. It doesn't save very much typing, but if you prefer to always use
the compiler-inferred delegate instantiation syntax, it's a useful
alternative.

Pete
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads

Dynamic event binding 3

Top